HDU 5961传递

 

 

思路分析:看到传递这个词应该可以想到二进制中有一种‘并’的操作,我们设有a,b两个值,只有a,b两个值都为1时a&b才唯一,所以我们考虑,如果从a到b有一条单向边,b到c有一条单向边,我们可以考虑开一个二维数组,将a中b对应的数位变为1,b中c对应的数位变为1,我们满足传递的条件是a中c对应的数位上也为1,那么我们可以让a和b对应的序列&一下,之后看一下得到的序列是否和b相等,(因为只有b能到的边a都能到时才成立),如果有不相等的情况,直接就失败了,反之则是一个传递,因为二维数组开不下,所以我们采用bitset存储。

不过本题中说p和q拼起来是一个完全图,可能蒟蒻写的是暴力没用到,暂时不太清楚有什么用。

代码:

 1 #include<cstdio>
 2 #include<bitset>
 3 #include<cstring>
 4 #include<algorithm>
 5 const int N=2016+10;
 6 using namespace std;
 7 bitset<N>bit_p[N]; //分别存储p图和q图 
 8 bitset<N>bit_q[N];
 9 int main(){
10     //freopen("a.txt","r",stdin);
11     int T;
12     scanf("%d",&T);
13     while(T--){
14         int n;
15         bool flag=0;
16         scanf("%d",&n);
17         for(int i=1;i<=n;++i){ //初始化 
18             bit_p[i].reset();
19             bit_q[i].reset();
20         }
21         for(int i=1;i<=n;++i)
22         for(int j=1;j<=n;++j){
23             char ch;
24             scanf(" %c",&ch);
25             if(ch=='P'){
26                 bit_p[i][j]=1; //p中i和j相连 
27             }
28             else if(ch=='Q'){  //q中i和j相连
29                 bit_q[i][j]=1;
30             }
31         }
32         for(int i=1;i<=n;++i){
33             for(int j=1;j<=n;++j){
34                 if(!bit_p[i][j]) continue; //首先i和j要相连 
35                 if(bit_p[j]==(bit_p[i]&bit_p[j])) continue; //传递成功 
36                 printf("N
");
37                 flag=1;break;
38             }
39             if(flag) break;
40         }
41         for(int i=1;i<=n;++i){  //同p 
42             for(int j=1;j<=n;++j){
43                 if(!bit_q[i][j]) continue;
44                 if(bit_q[j]==(bit_q[i]&bit_q[j])) continue;
45                 printf("N
");
46                 flag=1;break;
47             }
48             if(flag) break;
49         }
50         if(!flag) printf("T
");  //以上都满足 
51     }
52     return 0;
53 }
View Code
原文地址:https://www.cnblogs.com/li-jia-hao/p/12929974.html