POJ 2762 Going from u to v or from v to u? tarjan+缩点

http://poj.org/problem?id=2762

就是判断一个图是不是 弱连通

tarjan , 缩点之后,如果缩点图的 入度为一的点有一个 并且 出度为一的点 有一个 则是弱连通

开始把有向边都改成无向边 用dfs遍历  只要图连一块就是弱连通图 ,结果证明是错滴

下图

(图一)这个图就不连通,但是如果依照刚才的dfs把有向边变成无向边就错了

 

还有一个地方 

(图二)

#include<iostream>
#include<cstdio>
#include<cstring>
#define nMAX 10010
#define mMAX 50010
using namespace std;
int head[nMAX],belon[nMAX],out[nMAX],stack[nMAX],s_node[nMAX],
    dfn[nMAX],low[nMAX];
int atype,times,n,s_edge,top;
bool instack[nMAX];
struct Edge
{
    int u,v,nxt;
}edge[mMAX];
void addedge(int u,int v)
{
    s_edge++;
    edge[s_edge].u=u;
    edge[s_edge].v=v;
    edge[s_edge].nxt=head[u];
    head[u]=s_edge;
}
int min(int a,int b)
{
    return a<b?a:b;
}
void tarjan(int u)
{
    dfn[u]=low[u]=++times;
    instack[u]=1;
    stack[++top]=u;
    for(int e=head[u];e;e=edge[e].nxt)
    {
        int v=edge[e].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    int j;
    if(low[u]==dfn[u])
    {
        atype++;
        do{
            j=stack[top--];
            instack[j]=0;
            s_node[atype]++;
            belon[j]=atype;
        }while(j!=u);
    }
}
void init()
{
    atype=0;
    times=0;
    top=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(out,0,sizeof(out));
    memset(instack,0,sizeof(instack));
    memset(s_node,0,sizeof(s_node));
}
int main()
{
    int i,j,m;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        memset(head,0,sizeof(head));
        s_edge=0;
        while(m--)
        {
            scanf("%d%d",&i,&j);
            addedge(i,j);
        }
        for(i=1;i<=n;i++)
        {
            if(!dfn[i])tarjan(i);
        }
        //Ëõµã
        for(int e=1;e<=s_edge;e++)
        {
            int u=edge[e].u,v=edge[e].v;
            if(belon[u]!=belon[v])
                out[belon[u]]++;
        }
        int cnt=0,mark;
        for(i=1;i<=atype;i++)
        {
            if(out[i]==0)mark=i,cnt++;
        }
        if(cnt==1)printf("%d\n",s_node[mark]);
        else printf("0\n");
    }
    return 0;
}

  

posted @ 2012-02-10 05:38  快乐.  阅读(195)  评论(0编辑  收藏  举报