这道题刚看的时候觉扽它是一条最短路的问题,以为用flyod把每两个点之间的距离跑出来就欧克了,结果数据量太大是不行的,所以去看了一下大佬的代码,结果直接用搜索就可以了,不过就是有个优化的细节就是用的vector邻接表来存的边,然后从1到n遍历每一个顶点,然后再遍历下一个顶点邻接的下个顶点,看他们的距离是否大于二,这样每次搜索就能卡过时间。唉,比赛的时候一定要注意这些细节。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxm=2020;
int bookp[maxm][maxm],bookq[maxm][maxm];
char data[maxm][maxm];
int n;
vector<int>edgep[maxm],edgeq[maxm];
int dfsp(int u)
{
int d,v,k,j,i,w;
for(i=0;i<edgep[u].size();i++)
{
d=edgep[u][i];
for(j=0;j<edgep[d].size();j++)
{
k=edgep[d][j];
if(bookp[u][k]!=1) return 1;
}
}
return 0;
}
int dfsq(int u)
{
int d,v,k,j,i,w;
for(i=0;i<edgeq[u].size();i++)
{
d=edgeq[u][i];
for(j=0;j<edgeq[d].size();j++)
{
k=edgeq[d][j];
if(bookq[u][k]!=1) return 1;
}
}
return 0;
}
int main()
{
int i,j,t;
scanf("%d",&t);
int flagp,flagq;
while(t--)
{
flagp=flagq=0;
scanf("%d",&n);
for(i=0;i<=n;i++)
{
edgep[i].clear();
edgeq[i].clear();
}
for(i=0;i<n;i++)
{
scanf("%s",data+i);
for(j=0;j<n;j++)
{
bookp[i+1][j+1]=0;
bookq[i+1][j+1]=0;
if(data[i][j]=='P')
{
bookp[i+1][j+1]=1;
edgep[i+1].push_back(j+1);
}
if(data[i][j]=='Q')
{
bookq[i+1][j+1]=1;
edgeq[i+1].push_back(j+1);
}
}
}
for(i=1;i<=n;i++)
{
flagp=dfsp(i);
if(flagp)
break;
flagq=dfsq(i);
if(flagq)
break;
}
if(flagp==0&&flagq==0)
printf("T\n");
else printf("N\n");
}
return 0;
}