首页 > 其他 > 详细

【刷题】【割点和桥】冗余路径

时间:2019-10-28 23:13:17      阅读:65      评论:0      收藏:0      [点我收藏+]

对于同一对草场之间,可能已经有两条不同的道路

题真的应该看仔细啊

 

//一个问题,如何变成 边双联通分量 
//leaf+1>>1 
#include<cstdio>
#include<cstdlib>
#include<stack>
using namespace std;
inline int read()
{
    int x=0;char c=getchar();
    while(c<0 || c>9) c=getchar();
    while(c>=0&&c<=9) x=(x<<3)+(x<<1)+c-0,c=getchar();
    return x;
}
int n,m;
const int N=5003,M=10003;
int col[N],sum;

int tot=1,head[N]; 
int ev[M<<1],enx[M<<1];
void add(int u,int v)
{    ev[++tot]=v,enx[tot]=head[u],head[u]=tot;
    ev[++tot]=u,enx[tot]=head[v],head[v]=tot;    }

int dfn[N],low[N],cnt;
stack <int> s;
void tarjan(int rt,int pre)//强连通缩点
{
    dfn[rt]=low[rt]=++cnt;
    s.push(rt);
    
    for(int i=head[rt];i;i=enx[i])
        if((pre^1) != i )//对于同一对草场之间,可能已经有两条不同的道路
        {
            if(!dfn[ev[i]])
                tarjan(ev[i],i);    
            low[rt]=min(low[rt],low[ev[i]]);
        }
    if(dfn[rt]==low[rt])
    {
        col[rt]=++sum;
        while(s.top() !=rt)
            col[s.top() ]=sum,s.pop() ;
        s.pop() ;
    }    
}

int in[N];
int main()
{
    n=read(),m=read();
    for(int i=1;i<=m;i++)
        add(read(),read());
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            tarjan(i,0);
    
    int ans=0;
    for(int i=2;i<tot;i+=2)
        if(col[ev[i]]!=col[ev[i|1]] )
            in[col[ev[i]]]++,in[col[ev[i|1]]]++;
    for(int i=1;i<=sum;i++)
        if(in[i]==1) ans++; 
    printf("%d\n",ans+1>>1);
    return 0;
}

 

【刷题】【割点和桥】冗余路径

原文:https://www.cnblogs.com/xwww666666/p/11755478.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!