poj-3177(无向图缩点)

题意:给你n个点,m条边的无向联通图,问你最少增加几条边,使得这个图每对点至少有两条路径

解题思路:考虑每个环内的点必定有>=2条路径,所以先把这个无向图中的环去掉,用并查集缩环,然后剩下的图一定是个割边树,只需要把度为1的结点数/2就是答案了(把这棵树变成环);

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100500;
struct Edge
{
    int next;int to;int id;
}edge[maxn];
int head[maxn],cnt,low[maxn],visit[maxn],dfn[maxn],step,ans,n,m;
int f[maxn],x[maxn],y[maxn];
int deg[maxn];
void init()
{
    memset(deg,0,sizeof(deg));
    memset(head,-1,sizeof(head));
    memset(low,0,sizeof(low));
    memset(dfn,0,sizeof(dfn));
    for(int i=1;i<=n;i++)
        f[i]=i;
    cnt=step=0;
}
int findf(int u)
{
    if(f[u]==u)
        return u;
    else
    {
        f[u]=findf(f[u]);
        return f[u];
    }
}
void join(int u,int v)
{
    int t1=findf(u);int t2=findf(v);
    if(t2!=t1)
    {
        f[t2]=t1;
    }
}
void add(int u,int v,int id)
{
    edge[cnt].next=head[u];edge[cnt].to=v;edge[cnt].id=id;head[u]=cnt++;
    edge[cnt].next=head[v];edge[cnt].to=u;edge[cnt].id=id;head[v]=cnt++;
}
void tarjan(int u,int fa)
{
    dfn[u]=low[u]=++step;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        int id=edge[i].id;
        if(fa==id)
            continue;
        if(!dfn[v])
        {
            tarjan(v,id);
            low[u]=min(low[u],low[v]);
            if(dfn[u]<low[v])
            {
                ans++;
            }
            else
            {
                join(u,v);
            }
        }
        else
        {
            low[u]=min(low[u],dfn[v]);
        }
    }
}
int main()
{

    scanf("%d%d",&n,&m);init();
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
        add(x[i],y[i],i);
    }
    tarjan(1,0);
    for(int i=1;i<=m;i++)
    {
        if(findf(x[i])==findf(y[i]))
            continue;
        else
        {
            deg[findf(x[i])]++;deg[findf(y[i])]++;
        }
    }
    int cot=0;
    for(int i=1;i<=n;i++)
    {
        if(deg[i]==1)
            cot++;
    }
    printf("%d\n",(cot+1)/2);
}

 

posted @ 2019-03-31 16:13  荒岛的龟  阅读(488)  评论(0编辑  收藏  举报