POJ-3177-Redundant Paths

边双连通分量

这题的数据量比题目写的小,这题还需要判重,

2个确定的点之间的任何边都算same path,唔,不知道为什么,很弱看不懂题目。。。。

所以要先去重边,然后dfs求出桥,再dfs求出边双连通分量(只要不经过桥就行了)

问加多少条边使得任意两点都有两条不同边的路,就是求一个双连通分量

所以求出边双连通分量,然后缩点形成新图,

新图上度数为1的节点(即叶节点)数目为ans

(ans+1)/2 即为答案

View Code 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <stack>
#include <map>
using namespace std;
#define MAXN 1000+5
#define MAXM 10050*10
int F,R;
int e;
vector<int>G[MAXN],P[MAXN];
int dfs_clock,bcc_cnt;
int pre[MAXN];
int first2[MAXN];
int T[MAXN];
int M[MAXN][MAXN];
int dfs1(int u,int fa)
{
    int lowu=pre[u]=++dfs_clock;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(!pre[v])
        {
            int lowv=dfs1(v,u);
            lowu=min(lowu,lowv);
            if(lowv>pre[u])
            {
                P[v].push_back(u);
                P[u].push_back(v);
            }
        }
        else if(pre[v]<pre[u]&&v!=fa)
        {
            lowu=min(pre[v],lowu);
        }
    }
    return lowu;
}
void dfs2(int u,int fa)
{
    T[u]=bcc_cnt;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        bool f=true;
        for(int j=0;j<P[u].size();j++)
        {
            int vv=P[u][j];
            if(v==vv)
            {
                f=false;break;
            }
        }
        if(!f||T[v])continue;
        dfs2(v,u);
    }
}
void find_bcc(int n)
{
    dfs_clock=0,bcc_cnt=0;
    memset(pre,0,sizeof(pre));
    memset(T,0,sizeof(T));
    for(int i=1;i<=n;i++)
        if(!pre[i])
            dfs1(i,-1);
    for(int i=1;i<=n;i++)
        if(!T[i])
        {
            bcc_cnt++;
            dfs2(i,-1);
        }
}
int ans[MAXN];
int main()
{
  //  freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&F,&R))
    {
        int a,b;
        memset(M,0,sizeof(M));
        for(int i=0;i<MAXN;i++){
            G[i].clear();
            P[i].clear();
        }
        for(int i=0;i<R;i++)
        {
            scanf("%d%d",&a,&b);
            if(M[a][b]==1)continue;
            M[a][b]=M[b][a]=1;
            G[a].push_back(b);
            G[b].push_back(a);
        }
        find_bcc(F);
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=F;i++)
            for(int j=0;j<G[i].size();j++)
            {
                int v=G[i][j];
                if(T[i]!=T[v])
                    ans[T[i]]++;
            }
        int re=0;
        for(int i=1;i<=bcc_cnt;i++)
            if(ans[i]==1)
                re++;
        printf("%d\n",(re+1)/2);
    }
}

 

posted @ 2013-01-15 23:54  z.arbitrary  阅读(275)  评论(0编辑  收藏  举报