zoukankan      html  css  js  c++  java
  • POJ3177(3352)(边双连通分量)

    题目:

    原本没有记录桥是谁,而是染色时即时判断的。后来发现不行,因为a去b可能满足low[b]>dfn[a],但b去a就不满足了。

    这是因为low和dfn的关系是相对的,仅限于tarjan时的那棵dfs搜索树中。染色时没有按那棵树走,就不能用dfn和low了!

    累加ans时可以把边+=2,很方便。

    别忘了写v=edge[i].to。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,r,head[5005],xnt=1,dfn[5005],low[5005],col[5005];
    int x,y,tim,cnt,d[5005],ans;
    bool b[5005][5005],brg[20005];
    struct Edge{
        int next,to,from;
        Edge(int n=0,int t=0,int f=0):next(n),to(t),from(f) {}
    }edge[20005];
    void dfs(int cur,int fa)
    {
    //    printf("cur=%d
    ",cur);
        dfn[cur]=low[cur]=++tim;
        for(int i=head[cur],v;i;i=edge[i].next)
        {
            if(dfn[v=edge[i].to]&&v!=fa)
                low[cur]=min(low[cur],dfn[v]);
            if(!dfn[v])
            {
                dfs(v,cur);
                low[cur]=min(low[cur],low[v]);
                if(low[v]>dfn[cur])brg[i]=1,brg[i^1]=1;
            }
        }
    //    printf("cur=%d dfn=%d low=%d
    ",cur,dfn[cur],low[cur]);
    }
    void cl(int cur,int fa)
    {
        col[cur]=cnt;
    //    printf("cur=%d col=%d
    ",cur,cnt);
        for(int i=head[cur],v;i;i=edge[i].next)
        {
            if(edge[i].to==fa||brg[i])continue;
    //        printf("v=%d lowv=%d dfncur=%d
    ",edge[i].to,low[edge[i].to],dfn[cur]);
    //        if(low[v=edge[i].to]<=dfn[cur]&&!col[v])cl(v,cur);//避免环的死循环 //a去b是桥,b去a就不一定了 
            if(!col[v=edge[i].to])cl(v,cur);//
        }
    }
    int main()
    {
    //    freopen("POJ3177.in","r",stdin);
    //    freopen("poj3177.out","w",stdout);
    //    while(1)
    //    {
    //        xnt=1;cnt=0;ans=0;tim=0;
    //        memset(b,0,sizeof b);
    //        memset(col,0,sizeof col);
    //        memset(dfn,0,sizeof dfn);
    //        memset(low,0,sizeof low);
    //        memset(head,0,sizeof head);
    //        memset(d,0,sizeof d);
    //        memset(brg,0,sizeof brg);
            scanf("%d%d",&n,&r);
            for(int i=1;i<=r;i++)
            {
                scanf("%d%d",&x,&y);
                if(!b[x][y])
                {
                    b[x][y]=1;b[y][x]=1;
                    edge[++xnt]=Edge(head[x],y,x);head[x]=xnt;
                    edge[++xnt]=Edge(head[y],x,y);head[y]=xnt;
                }
            }
            dfs(1,0);
            for(int i=1;i<=n;i++)
                if(!col[i])
                {
                    cnt++;cl(i,0);
                }
            for(int i=2;i<=xnt;i+=2)
                if(col[edge[i].from]!=col[edge[i].to])
    //            if(brg[i])
                {
                    d[col[edge[i].from]]++;d[col[edge[i].to]]++;
    //                brg[i]=0;
    //                brg[i^1]=0;
                }
            for(int i=1;i<=cnt;i++)
                if(d[i]==1)ans++;
            printf("%d
    ",(ans+1)/2);
    //    }
        return 0;
    }
  • 相关阅读:
    Linux下select调用引发的血案
    http://www.regexlab.com/zh/regref.htm
    TPL: 一个新的C++正则表达式(regex)库
    Kerneloops为Linux用户与开发人员搭建“oops”报告提交桥梁
    LINUX同步软件rsync原理
    Oops错误
    C03Java同步实践加强班第9周上机任务
    C03Java同步实践加强班第8周上机任务
    关于读书:读XX书是否为时过早,是否有意义
    C++程序设计第八周上机实践项目
  • 原文地址:https://www.cnblogs.com/Narh/p/8667452.html
Copyright © 2011-2022 走看看