http://acm.hdu.edu.cn/showproblem.php?pid=5222
2 5 2 1 1 2 1 2 4 5 4 2 2 1 2 2 3 4 3 4 1
YES NOHintIf you need a larger stack size, please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
/**
hdu5222 拓扑+并查集
题目大意:给定一些有向边和无向边每个边只能走一次,问是否有环
解题思路:
首先对于所有的无向边,我们使用并查集将两边的点并起来
若一条边未合并之前,两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为这两个点处于同一个并查集集合中,那么它们之间至少存在一条路径)
如果上一步没有判断出环,那么仅靠无向边是找不到环的
考虑到,处于同一个并查集集合中的点之间必定存在一条路径互达,因此将一个集合的点合并之后,原问题等价于在新生成的有向图中是否有环
我们知道,有向无环图必定存在拓扑序,因此只需使用拓扑排序判定即可
时间复杂度O(N+M1+M2)
*/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
using namespace std;
const int maxn=1000006;
int n,m1,m2,flag;
int par[maxn],indegree[maxn],seq[maxn];
int indeg[maxn];
void init()
{
for(int i=0; i<=n; i++)
{
par[i]=i;
}
}
int find(int x)
{
if(par[x]==x)
return x;
return par[x]=find(par[x]);
}
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
{
flag=1;
return;
}
par[x]=y;
}
int head[maxn],ip;
void init1()
{
memset(head,-1,sizeof(head));
ip=0;
}
struct note
{
int v,next;
} edge[maxn];
void addedge(int u,int v)
{
edge[ip].v=v,edge[ip].next=head[u];
head[u]=ip++;
}
int topo()///拓扑
{
queue<int>q;
for(int i=1;i<=n;i++)
{
indeg[i]=indegree[i];
if(indeg[i]==0)
q.push(i);
}
int k=0;
while(!q.empty())
{
int u=q.front();
q.pop();
seq[k++]=u;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
indeg[v]--;
if(indeg[v]==0)
q.push(v);
}
}
// printf("(%d)\n",k);
if(k<n)return 0;
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m1,&m2);
flag=0;
init();
for(int i=0; i<m1; i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(flag)continue;
unite(u,v);
}
memset(indegree,0,sizeof(indegree));
init1();
for(int i=0; i<m2; i++)
{
int u,v;
scanf("%d%d",&u,&v);
u=find(u),v=find(v);
if(v==u)flag=1;
if(flag) continue;
addedge(u,v);
indegree[v]++;
}
if(!flag&&!topo())flag=1;
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
原文:http://blog.csdn.net/lvshubao1314/article/details/45605083