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

 1 /*
 2     题意:给出一个无向图,去掉一条权值最小边,使这个无向图不再连同!
 3
 4     tm太坑了...
 5     1,如果这个无向图开始就是一个非连通图,直接输出0
 6     2,重边(两个节点存在多条边, 权值不一样)
 7     3,如果找到了桥的最小权值为0,也就是桥上的士兵数为0,那么还是要最少派一个
 8     士兵过去炸掉桥!
 9
10     思路:假设每两个节点最多只有一条边进行相连!
11     进行tarjan算法,如果该算法调用了超过2次,说明这个原图就是不连通的!
12     否则在tarjan算法中将桥存起来!然后我们遍历每一座桥,看一看我们找到的
13     桥(连接的两个定点分别是u, v)是不是(u, v)只有一条路相连接,如果是的,
14     那么就跟新最小值!
15 */
16 #include<iostream>
17 #include<cstdio>
18 #include<cstring>
19 #include<algorithm>
20 #define M 1000005
21 #define INF 0x3f3f3f3f
22 #define N 1005
23 using namespace std;
24 struct EDGE{
25    int u, v, w, nt;
26    EDGE(){}
27    EDGE(int u, int v, int w, int nt){
28        this->u=u;
29        this->v=v;
30        this->w=w;
31        this->nt=nt;
32    }
33 };
34
35 EDGE edge[M];
36 EDGE brige[M];
37 int first[N];
38 int low[N], pre[N];
39 int dfs_clock;
40 int n, m, cnt, ret;
41
42
43 void tarjan(int u, int fa){
44     low[u]=pre[u]=++dfs_clock;
45     for(int e=first[u]; e!=-1; e=edge[e].nt){
46          int v=edge[e].v;
47
48          if(!pre[v]){
49               tarjan(v, u);
50               low[u]=min(low[u], low[v]);
51               if(low[v]>pre[u])
52                  brige[ret++]=edge[e];
53          }
54          else if(v!=fa && pre[u]>pre[v])
55               low[u]=min(low[u], pre[v]);
56     }
57 }
58
59 int main(){
60     while(scanf("%d%d", &n, &m) && (n||m)){
61         memset(first, -1, sizeof(first));
62         cnt=0;
63         while(m--){
64             int u, v, w;
65             scanf("%d%d%d", &u, &v, &w);
66             edge[cnt]=EDGE(u, v, w, first[u]);
67             first[u]=cnt++;
68             edge[cnt]=EDGE(v, u, w, first[v]);
69             first[v]=cnt++;
70         }
71         dfs_clock=0;
72         ret=0;
73         memset(low, 0, sizeof(low));
74         memset(pre, 0, sizeof(pre));
75         int flag=0;
76         for(int i=1; i<=n; ++i)
77            if(!pre[i]){
78               ++flag;
79               if(flag==2) break;
80               tarjan(i, -1);
81            }
82
83         int minNum=INF;
84         if(flag==2) minNum=0;
85         else{
86            for(int i=0; i<ret; ++i)
87              if(brige[i].w<minNum){//对假定的桥判断
88                 int cc=0;
89                 for(int e=first[brige[i].u]; e!=-1; e=edge[e].nt)
90                    if(edge[e].v==brige[i].v) ++cc;
91                 if(cc==1)  minNum=brige[i].w;//说明是真正的桥
92              }
93            if(minNum==INF) minNum=-1;
94            else if(minNum==0) minNum=1;//这一句不要忘记了!
95         }
96         printf("%d\n", minNum);
97     }
98     return 0;
99 }

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

时间: 2024-09-27 22:20:53

hdu Caocao's Bridges(无向图边双连通分量,找出权值最小的桥)的相关文章

HDU 4738 --Caocao&#39;s Bridges 【无向图边双联通 &amp;&amp; 求权值最小的桥 &amp;&amp; 模板】

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

hdu-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): 10933    Accepted Submission(s): 3065 Problem Description Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi.

HDU4738 Caocao&#39;s Bridges 无向图的桥

一眼题:找所有的桥,然后求最小权值 但是有很多坑点 1:如果本来不联通 输出0,(这个坑我知道) 2:但是还有一个坑,就是当整个连通,最小桥的权值是0时,也必须派一个人去,wa了无数遍(还是太年轻) #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include

hdu3844 Mining Your Own Business,无向图的双连通分量

点击打开链接 无向图的双连通分量 #include<cstdio> #include<stack> #include<vector> #include<map> #include<algorithm> #include<cstring> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; typedef long lo

连通分量 无向图的割顶和桥 无向图的双连通分量 有向图的强连通分量

时间戳 dfs_clock :说白了就是记录下访问每个结点的次序.假设我们用 pre 保存,那么如果 pre[u] > pre[v], 那么就可以知道先访问的 v ,后访问的 u . 现在给定一条边, (u, v), 且 u 的祖先为 fa, 如果有 pre[v] < pre[u] && v != fa, 那么 (u, v) 为一条反向边. 1 求连通分量: 相互可达的节点称为一个连通分量: #include <iostream> #include <cstd

ASC(22)C(最短路+双连通分量找桥或拓扑排序)

Important Roads Special JudgeTime Limit: 20000/10000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description The city where Georgie lives has n junctions some of which are connected by bidirectional r

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

图论--无向图点双连通分量模板

对于一个无向图,如果一个点集,它内部的任意一个点对之间,至少有两条点完全不重复的路径,那么这个点集就是原图的一个点双连通分量,而点双联通分量之间是由割点隔开,割点就是如果删去这个点,原图的连通块数会增加,那么这个点就是割点. 通过tarjan算法,我们可以用一次 dfs 标记出所有的割点以及所有双连通分量. 注释版: 1 #include<stdio.h> 2 #include<string.h> 3 #include<stack> 4 #include<algo

UVALive - 3523 Knights of the Round Table(无向图的双连通分量)

题目大意:有n个骑士经常举行圆桌会议,每次圆桌会议至少要有3个骑士参加(且每次参加的骑士数量是奇数个),且所有互相憎恨的骑士不能坐在圆桌旁的相邻位置,问有多少个骑士不可能参加任何一个会议 解题思路:以骑士为点建立无向图G.如果两个骑士可以相邻(即他们并不互相憎恨),即可连一条边. 则题目就转化为求不在任何一个简单奇圈上的结点个数 首先,圈就是一个双连通的分量,所以第一件事就是将所有的双连通分量求出来,接着再判定这个双连通分量是不是奇圈 奇圈的判定就是用二分图染色判定,如果某个圈能被二分图染色,那