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;
    }
  • 相关阅读:
    JavaBean和Map之间的转化
    java基础Map遍历
    sql server
    android之使用百度地图(1)
    Java基础知识2(字符串)
    Java基础知识1
    DAY12-Java中的类--接DAY10
    DAY11-LocalDate小练习
    DAY10-万物皆对象-2018-2-2
    DAY9-字符串笔记整理2018-1-19
  • 原文地址:https://www.cnblogs.com/Narh/p/8667452.html
Copyright © 2011-2022 走看看