*POJ 3177 Redundant Paths**

来源:互联网 发布:淘宝网店怎么装修视频 编辑:程序博客网 时间:2024/05/17 08:52

POJ 3177 Redundant Paths
这道题是求一个变双联通分量,问你,最少加多少条边,可以使任意两个节点之间可以有两条路径
首先我们要知道,通过联通分量缩点以后我们可以形成一棵树,那么树的叶子节点数为cnt, (cnt+1)/2 便是答案,
然后就是Trajan求割边了,

#include <iostream>#include <stdlib.h>#include <stdio.h>#include <string.h>using namespace std;#define MAXN 55555#define MAXE 311111struct Edge{    int u, v, next;} e[MAXE];int head[MAXE], cnt;int dfn[MAXN], low[MAXN], out[MAXN], vis[MAXN];int bri[MAXN][2], fa[MAXN], belong[MAXN];int blo, dep, nbri;void init(){    cnt = blo = dep = nbri = 0;    memset(head, -1, sizeof(head));    memset(belong, -1, sizeof(belong));    memset(fa, -1, sizeof(fa));    memset(vis, 0, sizeof(vis));    memset(out, 0, sizeof(low));}int findfa(int x){    if(fa[x] == -1) return x;    return fa[x] = findfa(fa[x]);}void unit(int x, int y){    int fax = findfa(x);    int fay = findfa(y);    if(fax != fay)        fa[fax] = fay;}void Addedge( int uu, int vv){    e[cnt].u = uu, e[cnt].v = vv, e[cnt].next = head[uu];    head[uu] = cnt++;}void dfs( int u, int fa){    vis[u] = 1;    dfn[u] = low[u] = ++ dep;    int pre_num = 0;    for( int i = head[u] ; i != -1; i = e[i].next)    {        int v = e[i].v;        if( v == fa && !pre_num)        {            pre_num = 1;            continue;        }        if(vis[v] == 0)        {            dfs(v, u);            low[u] = min(low[u], low[v]);            if(low[v] > dfn[u])            {                bri[nbri][0] = u;                bri[nbri][1] = v;                nbri++;            }            else             unit(u, v);        }        else if(vis[v] == 1)          low[u] = min(low[u], dfn[v]);    }    vis[u] = 1;}void solve( int n, int m){    for(int i = 1; i <= n; i++)         if(!dfn[i])           dfs(i, -1);    int node = 1;    for( int i = 1; i <= n; i++)    {        int k = findfa(i);        if(belong[k] == -1) belong[k] = node++;        belong[i] = belong[k];    }    int count = 0;    for( int i = 0; i < nbri; i++)    {        int u = bri[i][0], v = bri[i][1];        out[belong[u]]++;        out[belong[v]]++;    }    for( int i = 0; i < node; i++)     if(out[i] == 1) count++;    printf("%d\n",(count+1)/2);}int main(){    int n, m, u, v;    while(scanf("%d %d",&n, &m) != EOF)    {        init();        for( int i = 1; i <= m; i++)        {            scanf("%d %d",&u, &v);            if( u == v) continue;            Addedge(u, v);            Addedge(v, u);        }        solve(n ,m);    }    return 0;}
0 0
原创粉丝点击