链接
http://acm.hdu.edu.cn/showproblem.php?pid=5961
题解
其实这题很简单,但主要是我对图论不很熟悉…
如果传递的话,那么
a
→
b
a\rightarrow b
a→b且
b
→
c
b\rightarrow c
b→c则
a
→
c
a \rightarrow c
a→c
那就是说,
b
b
b能到达的点,
a
a
a都能到(前提是
a
a
a能到
b
b
b)
那我就对于每个
a
a
a,枚举能到达的
b
b
b,然后看看
b
b
b能到达的点是不是
a
a
a能到达的点的子集
可达性显然能并行计算,因此时间复杂度可以达到
O
(
n
3
w
)
O(\frac{n^3}{w})
O(wn3),其中
w
w
w是多少位一起并行计算(用c++的
b
i
t
s
e
t
bitset
bitset的话
w
=
32
w=32
w=32,如果在
64
64
64位机器上用
l
o
n
g
l
o
n
g
long\ long
long long理论可达到
w
=
64
w=64
w=64)
代码
#include <bits/stdc++.h>
#define maxn 2019
using namespace std;
bitset<maxn> P[maxn], Q[maxn];
int N;
bool judge(bitset<maxn>* to)
{
int i, j;
for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
if(to[i].test(j))
{
if( (to[j]&to[i]) != to[j])return false;
}
}
}
return true;
}
char s[maxn];
int main()
{
int T, i, j;
ios::sync_with_stdio(false);
cin>>T;
while(T--)
{
cin>>N;
for(i=1;i<=N;i++)P[i].reset(), Q[i].reset();
for(i=1;i<=N;i++)
{
cin>>s+1;
for(j=1;j<=N;j++)
{
if(s[j]=='P')P[i].set(j);
if(s[j]=='Q')Q[i].set(j);
}
}
if(judge(P) and judge(Q))
{
printf("T\n");
}
else printf("N\n");
}
return 0;
}