hdu 3594 Cactus

http://acm.hdu.edu.cn/showproblem.php?pid=3594

这是一个很好的题目,很巧的利用的low[u]和dfn[u]。如果low[u]!=dfn[u],则说明已经存在环,如果我们访问u点时发现low[u]!=dfn[u],则说明有一条边在两个环上了。

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stack>
#include<algorithm>
#include<utility>
using namespace std;
const int maxn = 20005;
struct nd
{
        int to,next;
}edge[maxn*5];

int dfn[maxn],vis[maxn];
int flag[maxn],head[maxn];
int ecnt,cnt,idx,ok,low[maxn];
stack<int>st;
void add(int s,int t)
{
        edge[ecnt].to = t;
        edge[ecnt].next = head[s];
        head[s] = ecnt++;
}
void tarjan(int u)
{
        int i,v;
        if(ok)return;
        dfn[u] = low[u] = ++idx;
        vis[u] = 1;
        st.push(u);
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].to;
                if(dfn[v]==0){
                        tarjan(v);
                        low[u] = min(low[v],low[u]);
                }else if(vis[v]){
                        low[u] = min(dfn[v],low[u]);
                        if(dfn[v]!=low[v]) ok = 1;
                }
                if(ok)return;
        }
        if(dfn[u]==low[u])
        {
                cnt++;
                if(cnt>1)ok=1;
                do{
                        v = st.top();
                        st.pop();
                        vis[v] = 0;
                }while(st.top()!=u);
        }
}
int main()
{
        int i,j,s,t,n,cas;
        scanf("%d",&cas);
        while(cas--)
        {
                scanf("%d",&n);
                memset(vis,0,sizeof(vis));
                memset(head,-1,sizeof(head));
                memset(flag,0,sizeof(flag));
                memset(dfn,0,sizeof(dfn));
                ecnt = cnt = idx = 0;

                scanf("%d %d",&s,&t);
                while(s+t){
                        ++s; ++t;
                        add(s,t);
                        scanf("%d %d",&s,&t);
                }

                while(!st.empty()) st.pop();
                ok = 0;
                for(i = 1; i <= n; ++ i)if(!dfn[i]) tarjan(i);
                if(ok||cnt!=1)puts("NO");
                else puts("YES");
        }
        return 0;
}

 

posted on 2012-06-19 17:35  aigoruan  阅读(226)  评论(2)    收藏  举报

导航