传 话
Time Limit:10000MS Memory Limit:65536K
Total Submit:24 Accepted:7
Case Time Limit:1000MS
Description
问题描述:兴趣小组的同学来自各个学校,为了增加友谊,晚会上又进行了一个传话游戏
如果A认识B,那么A收到消息,就会把消息传给B,以及所有A认识的人。
如果A认识B,B不一定认识A。
所有人从1到N编号,给出所有认识关系,问如果I发布一条消息,那么会不会经过若干次传话后,这个消息传回给了I,1<=i<=n。
Input
第一行是两个数N(N<1000)和M(M<10000),表示人数和认识关系数。
接下来M行,每行两个数A和B,表示A认识B。认识关系可能会重复给出,但一行的两个数不会相同。
Output
输出文件中一共有N行,每行一个字符T或F,从I发出一条消息,若能传回I则第I行为T,否则为F。
Sample Input
4 6
1 2
2 3
4 1
3 1
1 3
2 3
Sample Output
T
T
T
F
判断 图的连通性,两种方法一种BFS,一种DFS,一开始用二维数组标记超时了,其实这题只要用一维就可以了。而且不用回溯的,
因为如果搜索到某层K,如果不是由i层转回到i层的一条回路,而是一条死路,那么以后必然也不用搜索这层了。
下面是AC代码:
#include<iostream> #include<queue> using namespace std; bool f[1010][1010]; bool mark[1010]; int n,m,a,b,flag,i; typedef pair<int ,int > pll; /*void dfs(int cur){ for(int p=1;p<=n;p++){ if(f[cur][p]) { if(!mark[p]){ mark[p]=1; dfs(p); if(mark[i]) { flag=1; return ; } } } } }*/ void bfs(int start){ queue<int >q; int p; q.push(start); while(!q.empty()){ int temp=q.front(); q.pop(); // if(temp=i) { flag=1; return 1;} for(p=1;p<=n;p++){ if(f[temp][p]&&!mark[p]) { mark[p]=1; q.push(p); } if(mark[i]) { flag=1; return ; } } } } int main(){ cin>>n>>m; memset(f,0,sizeof(f)); for(i=0;i<m;i++) scanf("%d%d",&a,&b), f[a][b]=1; for(i=1;i<=n;i++) { memset(mark,0,sizeof(mark)); flag=0; bfs(i); if(flag) printf("T\n"); else printf("F\n"); } return 0; }