3 2 0 1 1 2 2 2 0 1 1 0 0 0
YES NO
题意 :一个可以有多个师傅,或者多个徒弟。 师傅的师傅的一样是自己的师傅,徒弟的徒弟的,一样是自己的徒弟。
但是一个人不能即是一个人的师傅,也是这个人的徒弟。问 如果存在这种混乱关系的,就输出NO, 否则输出 YES.
题解:强连通判断各个点是否各自为一个强连通分量,即强连通分量为n个为YES,否则为NO。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
using namespace std;
const int maxn=1e2+5;
struct Edge {
int to,nxt;
} edge[maxn];
int head[maxn],tot;
int low[maxn],dfn[maxn],Stack[maxn];
int id,top;
int scc;
int n,m;
bool Instack[maxn];
void addedge(int u,int v) {
edge[tot].to=v;
edge[tot].nxt=head[u];
head[u]=tot++;
}
void tarjan(int u) {
int v;
low[u]=dfn[u]=++id;
Stack[top++]=u;
Instack[u]=true;
for(int i=head[u]; i!=-1; i=edge[i].nxt) {
v=edge[i].to;
if(!dfn[v]) {
tarjan(v);
if(low[v]<low[u])
low[u]=low[v];
} else if(Instack[v]&&low[u]>dfn[v])
low[u]=dfn[v];
}
if(low[u]==dfn[u]) {
scc++;
do {
v=Stack[--top];
Instack[v]=false;
} while(v!=u);
}
}
void solve() {
id=scc=top=0;
memset(Instack,false,sizeof(Instack));
memset(dfn,false,sizeof(dfn));
for(int i=0; i<n; i++) {
if(!dfn[i])
tarjan(i);
}
if(scc==n)
puts("YES");
else
puts("NO");
}
int main() {
while(~scanf("%d%d",&n,&m)) {
if(n==0)
break;
tot=0;
memset(head,-1,sizeof(head));
while(m--) {
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
}
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/47737863