http://acm.hdu.edu.cn/showproblem.php?pid=3342
题目大意:在n个人中间存在m条师徒关系,且师徒关系具有传递效应,判断这些关系是否合理;
思路1:若关系不合理,必定存在环路。用最短路的floyd算法找出所有可以联系的人,如果一个人与自己有联系,则说明存环路。
思路2:对n个点按给出的关系进行拓扑排序,若排序完成则说明不存在环路,否则存在环路。
方法一:floyd
#include<iostream> #include<stdio.h> #include<string.h> #include<stdlib.h> using namespace std; int map[101][101]; void floyd(int n) { int i,j,k; for(k=0;k<n;k++){ for(i=0;i<n;i++){ for(j=0;j<n;j++){ if(map[i][k]&&map[k][j]) map[i][j]=1; } } } } int main() { int i,n,m,a,b,flag; while(scanf("%d%d",&n,&m),n){ flag=1; memset(map,0,sizeof(map)); for(i=0;i<m;i++){ scanf("%d%d",&a,&b); if(a!=b) map[a][b]=1; } floyd(n); for(i=0;i<n;i++){ if(map[i][i]){ flag=0;break; } } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }方法二:toposort
#include<iostream> #include<stdio.h> #include<string.h> #include<stdlib.h> using namespace std; int map[101][101],in[101]; int toposort(int n) { int i,j,k,cnt=0; for(i=0;i<n;i++){ for(j=0;j<n;j++){ if(in[j]==0){ in[j]--; cnt++; if(cnt==n) return cnt; for(k=0;k<n;k++){ if(map[j][k]) in[k]--; } } } } return cnt; } int main() { int n,m,i,a,b; while(scanf("%d%d",&n,&m),n){ memset(map,0,sizeof(map)); memset(in,0,sizeof(in)); for(i=0;i<m;i++){ scanf("%d%d",&a,&b); if(a!=b && map[a][b]==0){ map[a][b]=1; in[b]++; } } if(toposort(n)==n) puts("YES"); else puts("NO"); } return 0; }