hdu 5961 传递
传递
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1325 Accepted Submission(s): 599
Problem Description
我们称一个有向图G是传递的,当且仅当对任意三个不同的顶点a,,若G中有 一条边从a到b且有一条边从b到c ,则G中同样有一条边从a到c。
我们称图G是一个竞赛图,当且仅当它是一个有向图且它的基图是完全图。换句 话说,将完全图每条边定向将得到一个竞赛图。
下图展示的是一个有4个顶点的竞赛图。
现在,给你两个有向图P = (V,Ep)和Q = (V,Ee),满足:
1. EP与Ee没有公共边;
2. (V,Ep⋃Ee)是一个竞赛图。
你的任务是:判定是否P,Q同时为传递的。
我们称图G是一个竞赛图,当且仅当它是一个有向图且它的基图是完全图。换句 话说,将完全图每条边定向将得到一个竞赛图。
下图展示的是一个有4个顶点的竞赛图。
现在,给你两个有向图P = (V,Ep)和Q = (V,Ee),满足:
1. EP与Ee没有公共边;
2. (V,Ep⋃Ee)是一个竞赛图。
你的任务是:判定是否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。保证输入的图一定满足给出的限制条件。
第一行有一个正整数,表示数据的组数。
对于每组数据,第一行有一个正整数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
注:在样例2中,P不是传递的。在样例4中,Q不是传递的。
Hint
在下面的示意图中,左图为图为Q。思路:bitset
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=2100; 4 5 char s[N][N]; 6 bitset<N> a[N],xx; 7 8 int main(){ 9 int t; 10 cin>>t; 11 while(t--){ 12 int n; 13 scanf("%d",&n); 14 for(int i=1;i<=n;i++){ 15 scanf("%s",s[i]+1); 16 } 17 for(int i=1;i<=n;i++) 18 a[i].reset(); 19 for(int i=1;i<=n;i++){ 20 for(int j=1;j<=n;j++) 21 if(s[i][j]=='P'){ 22 a[i][j]=1; 23 } 24 } 25 int tt=0; 26 for(int i=1;i<=n;i++){ 27 for(int j=1;j<=n;j++){ 28 if(a[i][j]){ 29 xx=a[i]&a[j]; 30 if(xx!=a[j]){ 31 tt=1;break; 32 } 33 } 34 } 35 if(tt) break; 36 } 37 38 if(tt) { 39 printf("N\n");continue; 40 } 41 42 for(int i=1;i<=n;i++) 43 a[i].reset(); 44 for(int i=1;i<=n;i++){ 45 for(int j=1;j<=n;j++) 46 if(s[i][j]=='Q'){ 47 a[i][j]=1; 48 } 49 } 50 51 for(int i=1;i<=n;i++){ 52 for(int j=1;j<=n;j++){ 53 if(a[i][j]){ 54 xx=a[i]&a[j]; 55 if(xx!=a[j]){ 56 tt=1;break; 57 } 58 } 59 } 60 if(tt) break; 61 } 62 if(tt) printf("N\n"); 63 else printf("T\n"); 64 } 65 return 0; 66 }