【并查集+强连通】 HDU 5222 Exploration

来源:互联网 发布:淘宝已买到宝贝提取器 编辑:程序博客网 时间:2024/06/16 10:02

点击打开链接

对于有向图: 对于一条边u,v 若uv在一个集合内则成环

对于无向图:用强向量判断

#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#include<queue>#include <string>#include <sstream>#include <map>#include <vector>#define LL long long#define N 1000100#pragma comment(linker, "/STACK:102400000,102400000")vector<int>g[N];int n,m1,m2;int DFN[N],Low[N],Stack[N],Time,top;int taj,Belong[N],ok;bool Instack[N];void tarjan(int u,int fa){    DFN[u]=Low[u]=++Time;    Stack[top++] = u;    Instack[u]=1;    for(int i=0;i<g[u].size();i++)    {        int v=g[u][i];        if(DFN[v]==-1)        {            tarjan(v,u);            Low[u]=min(Low[u],Low[v]);        }        else if(Instack[v]) Low[u]=min(Low[u],DFN[v]);    }    if(Low[u]==DFN[u])    {        int now,num=0;        taj++;        do{            now=Stack[--top];            Instack[now]=0;            Belong[now]=taj;            num++;            if(num>1) ok=1;//两个点成环        }while(now!=u);    }}void tarjan_init(int all){    memset(DFN,-1,sizeof(DFN));    memset(Instack,0,sizeof(Instack));    top=Time=taj=0;    for(int i=1;i<=all;++i)        if(DFN[i]==-1) tarjan(i,i);}int fa[N];int find(int a){    if(a!=fa[a])        return fa[a]=find(fa[a]);    else return fa[a];}int main(){    int t,a,b;    cin>>t;    while(t--)    {        cin>>n>>m1>>m2;        for(int i=1;i<=n;i++)            g[i].clear(),fa[i]=i;        ok=0;        for(int i=0;i<m1;++i)//无向图        {            scanf("%d%d",&a,&b);            int x=find(a);            int y=find(b);            if(x==y) ok=1;            fa[x]=y;        }        for(int i=0;i<m2;++i)//有向图        {            scanf("%d%d",&a,&b);            int x=find(a);            int y=find(b);            if(x==y) ok=1;            g[x].push_back(y);//集合        }        tarjan_init(n);        if(ok) puts("YES");        else puts("NO");    }    return 0;}/*3 1 21 21 33 2*/


0 0
原创粉丝点击