Source
题意: 这是CCPC2016合肥站的A题,当时纠结在题目给出的竞赛图这个概念,但是看了解题报告后才发现并不需要用到竞赛图。思路很简单就是对每个点做一次BFS,只要有深度>1的点就说明这个图不是传递的。同时有必要用vector优化一下。
首先vector的用法
头文件:#include<vector>
声明:vector<int> v (也可以声明数组形式v[100])
基本操作:
- v.clear()移除容器中所有数据 注意:用于初始化,一定不能忘记清零操作
- v.empty() v空时返回true
- v.size() 返回数组中元素的个数
- v.front() 返回数组第一个元素
- v.push_back(x) 将x加到数组尾部中 注意:不是其它STL用的push()
- v.pop_back() 删除最后一个数据。
- v.insert(p,x) 在p位置插入x
- v.erase(p) 删除p位置的数据
- v.erase(beg,end) 删除[beg,end)区间的数据
- 直接用数组访问下标的方式访问即可
然后代码如下:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
#define maxn 2020
vector<int> e[maxn][2]; //两个图
int BFS(int m,int k)
{
queue<int> q;
int fr,cur;
int d[maxn];
memset(d,0,sizeof(d));
q.push(m);
while(!q.empty())
{
fr=q.front();
q.pop();
for(int i=0;i<e[fr][k].size();i++)
if(d[e[fr][k][i]]==0)
{
cur=e[fr][k][i];
q.push(cur);
d[cur]=d[fr]+1;
if(d[cur]>1) return 1;
}
}
return 0;
}
int main()
{
int n,i,j,t,flag0,flag1;
char s[maxn];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
//清零操作
for(i=0;i<n;i++)
{
e[i][0].clear();
e[i][1].clear();
}
//读入
for(i=0;i<n;i++)
{
scanf("%s",s);
for(j=0;j<n;j++)
switch(s[j])
{
case 'P':e[i][0].push_back(j);break;
case 'Q':e[i][1].push_back(j);break;
default:break;
}
}
//对每个点进行两次BFS
flag0=flag1=0;
for(i=0;i<n;i++)
{
flag0=BFS(i,0);
if(flag0) break;
flag1=BFS(i,1);
if(flag1) break;
}
if(flag0 || flag1) printf("N\n");
else printf("T\n");
}
return 0;
}