Gym - 100712H Bridges(边—双连通分量)

https://vjudge.net/problem/Gym-100712H

题意:

给出一个图,求添加一条边后最少的桥数量。

思路:

参考了ZSQ大神的题解http://blog.csdn.net/v5zsq/article/details/61922051

很明显的边—双连通的题目,首先缩点建新图。然后寻找树中的最大直径,这样就能将桥的数量减至最小。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<queue>
  7 #include<cmath>
  8 #include<map>
  9 #include<stack>
 10 using namespace std;
 11
 12 const int maxn=100000+5;
 13
 14 struct Edge
 15 {
 16     int to,next;
 17     bool flag;//标记是否是桥
 18 }edge[maxn*2];
 19
 20 stack<int> S;
 21 int n,m;
 22 int head[maxn],tot;
 23 int low[maxn],dfn[maxn],belong[maxn];
 24 int index,top;
 25 int block;//边双连通块数
 26 bool instack[maxn];
 27 int bridge;//桥的数目
 28 int e[maxn][2];
 29 int deep;   //最长直径
 30 int pos;    //最长直径端点
 31
 32 void addedge(int u,int v)
 33 {
 34     edge[tot].to=v,edge[tot].next=head[u],edge[tot].flag=0;
 35     head[u]=tot++;
 36 }
 37
 38 void Tarjan(int u,int pre)
 39 {
 40     int v;
 41     low[u]=dfn[u]=++index;
 42     S.push(u);
 43     instack[u]=1;
 44     for(int i=head[u];~i;i=edge[i].next)
 45     {
 46         v=edge[i].to;
 47         if(v==pre)continue;
 48         if(!dfn[v])
 49         {
 50             Tarjan(v,u);
 51             if(low[u]>low[v])low[u]=low[v];
 52             if(low[v]>dfn[u])
 53             {
 54                 bridge++;
 55                 edge[i].flag=1;
 56                 edge[i^1].flag=1;
 57             }
 58         }
 59         else if(instack[v]&&low[u]>dfn[v])
 60             low[u]=dfn[v];
 61     }
 62     if(low[u]==dfn[u])
 63     {
 64         block++;
 65         do
 66         {
 67             v=S.top(); S.pop();
 68             instack[v]=0;
 69             belong[v]=block;
 70         }
 71         while(v!=u);
 72      }
 73 }
 74
 75 void init()
 76 {
 77     memset(dfn,0,sizeof(dfn));
 78     index=block=top=bridge=tot=0;
 79     memset(head,-1,sizeof(head));
 80 }
 81
 82 //邻接表寻找树的直径
 83 void dfs(int u,int fa,int cnt)
 84 {
 85     if(cnt>deep)  {deep=cnt;pos=u;}
 86     for(int i=head[u];~i;i=edge[i].next)
 87     {
 88         int v=edge[i].to;
 89         if(v!=fa)  dfs(v,u,cnt+1);
 90     }
 91 }
 92
 93 int main()
 94 {
 95     //freopen("D:\\input.txt","r",stdin);
 96     int T;
 97     scanf("%d",&T);
 98     while(T--)
 99     {
100         scanf("%d%d",&n,&m);
101         init();
102         for(int i=1;i<=m;i++)
103         {
104             scanf("%d%d",&e[i][0],&e[i][1]);
105             addedge(e[i][0],e[i][1]);
106             addedge(e[i][1],e[i][0]);
107         }
108         Tarjan(1,1);
109
110         //缩点,重建图
111         tot=0;
112         memset(head,-1,sizeof(head));
113         int ans=0;
114         for(int i=1;i<=m;i++)
115         {
116             int u=belong[e[i][0]], v=belong[e[i][1]];
117             if(u!=v)
118             {
119                 ans++;
120                 addedge(u,v);
121                 addedge(v,u);
122             }
123         }
124
125         deep=0;
126         dfs(1,1,0);
127         deep=0;
128         dfs(pos,pos,0);
129         printf("%d\n",ans-deep);
130     }
131     return 0;
132 }
时间: 2024-10-20 08:23:42

Gym - 100712H Bridges(边—双连通分量)的相关文章

hdoj 4738 Caocao&#39;s Bridges【双连通分量求桥】

Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3000    Accepted Submission(s): 953 Problem Description Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. Bu

zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】

Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little country located on N islands that are connected by M bridges. All bridges are very beautiful and are loved by everyone in the kingdom. Of course, the sys

ZOJ2588.Burning Bridges——边双连通分量,有重边

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 题目描述: Ferry 王国是一个漂亮的岛国,一共有N 个岛国.M 座桥,通过这些桥可以从每个小岛都能到达任何一个小岛.很不幸的是,最近Ferry 王国被Jordan 征服了.Jordan 决定烧毁所有的桥.这是个残酷的决定,但是Jordan 的谋士建议他不要这样做,因为如果烧毁所有的桥梁,他自己的军队也不能从一个岛到达另一个岛.因此Jordan 决定烧尽可能多的桥,只

hdu Caocao&#39;s Bridges(无向图边双连通分量,找出权值最小的桥)

1 /* 2 题意:给出一个无向图,去掉一条权值最小边,使这个无向图不再连同! 3 4 tm太坑了... 5 1,如果这个无向图开始就是一个非连通图,直接输出0 6 2,重边(两个节点存在多条边, 权值不一样) 7 3,如果找到了桥的最小权值为0,也就是桥上的士兵数为0,那么还是要最少派一个 8 士兵过去炸掉桥! 9 10 思路:假设每两个节点最多只有一条边进行相连! 11 进行tarjan算法,如果该算法调用了超过2次,说明这个原图就是不连通的! 12 否则在tarjan算法中将桥存起来!然后

HDU 4612——Warm up——————【边双连通分量、树的直径】

Warm up Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4612 Description N planets are connected by M bidirectional channels that allow instant transportation. It's always possible to travel bet

[HDOJ4738]Caocao&#39;s Bridges(双联通分量,割边,tarjan)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 给一张无向图,每一条边都有权值.找一条割边,使得删掉这条边双连通分量数量增加,求权值最小那条. 注意有重边,ACEveryDay里群巨给的意见是tarjan的时候记录当前点是从哪条边来的. 注意假如桥的权值是0的时候也得有一个人去炸…… 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7

【连通图|边双连通分量+Tarjan+并查集】POJ-3694 Network(400+ms)

Network Time Limit: 5000MS Memory Limit: 65536K Description A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers are connected directly or indirectly by suc

hdoj 4612 Warm up【双连通分量求桥&amp;&amp;缩点建新图求树的直径】

Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 5093    Accepted Submission(s): 1131 Problem Description N planets are connected by M bidirectional channels that allow instant transport

Poj 3352 Road Construction &amp; Poj 3177 Redundant Paths(边双连通分量+缩点)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9465   Accepted: 4699 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro