HDU 5961&AOJ 821 传递

题面:
Problem Description
我们称一个有向图G是传递的,当且仅当对任意三个不同的顶点a,,若G中有 一条边从a到b且有一条边从b到c ,则G中同样有一条边从a到c。
我们称图G是一个竞赛图,当且仅当它是一个有向图且它的基图是完全图。换句 话说,将完全图每条边定向将得到一个竞赛图。
下图展示的是一个有4个顶点的竞赛图。

现在,给你两个有向图P = (V,Ep)和Q = (V,Ee),满足:
1.   EPEe没有公共边;
2.  (V,EpEe)是一个竞赛图。
你的任务是:判定是否P,Q同时为传递的。

 
Input
包含至多20组测试数据。
第一行有一个正整数,表示数据的组数。
对于每组数据,第一行有一个正整数n。接下来n行,每行为连续的n个字符,每 个字符只可能是’-’,’P’,’Q’中的一种。
如果第i行的第j个字符为’P’,表示有向图P中有一条边从i到j;
如果第i行的第j个字符为’Q’,表示有向图Q中有一条边从i到j;
否则表示两个图中均没有边从i到j。
保证1 <= n <= 2016,一个测试点中的多组数据中的n的和不超过16000。保证输入的图一定满足给出的限制条件。
 
Output
对每个数据,你需要输出一行。如果P! Q都是传递的,那么请输出’T’。否则, 请输出’N’ (均不包括引号)。
 
Sample Input
4 4 -PPP --PQ ---Q ---- 4 -P-P --PQ P--Q ---- 4 -PPP --QQ ---- --Q- 4 -PPP --PQ ---- --Q-
 
Sample Output
T N T N
大致思路:
由题中说的传递关系,可以知道这个关系存只在于任意三个点中,而不是一般意义上的一条长链一样的传递关系 
所以对于P图和Q图的每一个点遍历一遍,看对于每一个子节点的子节点(如果存在的话)是否有直接到达的路径,如果没有,就不满足传递关系。
代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2020;
 4 int gp[maxn][maxn];
 5 int gq[maxn][maxn];
 6 vector<int> mp[maxn];
 7 vector<int> mq[maxn];
 8 bool check_P(int x)
 9 {
10     int v,u;
11     for(int i=0;i<mp[x].size();++i){
12         v=mp[x][i];
13         for(int j=0;j<mp[v].size();++j){
14             u=mp[v][j];
15             if(gp[x][u]!=1)
16                 return false;
17         }
18     }
19     return true;
20 }
21 bool check_Q(int x)
22 {
23     int v,u;
24     for(int i=0;i<mq[x].size();++i){
25         v=mq[x][i];
26         for(int j=0;j<mq[v].size();++j){
27             u=mq[v][j];
28             if(gq[x][u]!=1)
29                 return false;
30         }
31     }
32     return true;
33 }
34 int main()
35 {
36     ios::sync_with_stdio(false);
37     //freopen("in.txt","r",stdin);
38     int t,n;
39     char s[maxn];
40     cin>>t;
41     while(t--)
42     {
43         memset(gp,0,sizeof(gp));
44         memset(gq,0,sizeof(gq));
45         cin>>n;
46         for(int i=1;i<=n;++i){
47             mp[i].clear();
48             mq[i].clear();
49         }
50         for(int i=1;i<=n;++i){
51             cin>>s+1;
52             for(int j=1;j<=n;++j){
53                 if(s[j]=='P'){
54                     gp[i][j]=1;
55                     mp[i].push_back(j);
56                 }
57                 else if(s[j]=='Q'){
58                     gq[i][j]=1;
59                     mq[i].push_back(j);
60                 }
61             }
62         }
63         bool flag=true;
64         for(int i=1;i<=n;++i){
65             if(check_P(i)==false||check_Q(i)==false){
66                 flag=false;
67                 break;
68             }
69         }
70         if(flag)
71             cout<<"T"<<endl;
72         else
73             cout<<"N"<<endl;
74     }
75     return 0;
76 }
原文地址:https://www.cnblogs.com/SCaryon/p/7374897.html