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;
}