Caocao's Bridges

hdu4738:http://acm.hdu.edu.cn/showproblem.php?pid=4738

题意:抽象出来就是求一条边权最小的割边。

题解:直接用tarjan即可破。但是如果只注重这里你就错了,就是边权为0 的桥也要一个人去炸。

 1 #pragma comment(linker,"/STACK:100000000,100000000")//阔栈的语句
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <vector>
 5 #define pb push_back
 6 using namespace std;
 7 const int maxn = 200002;
 8 const int maxm = 1000002;
 9 struct EDGE{
10     int next, to, vis,w;
11 }edge[maxm*2];//记录边,vis表示这一条边是否被访问
12 struct GEEDGE {
13     int u, to;
14 }geedge[maxm];//记录割边
15 int n,m,time,top,w,type,getot,cnt;//time是时间戳,type标记连通块,getot割边的数量,cnt边数
16 int head[maxn],st[maxn],dfn[maxn],low[maxn],belo[maxn];//belo[i],表示i属于哪个连通块
17 int start,ans1,ans,u,v,tval[maxn];
18 void init(){
19     time=top=type=getot=cnt=0;
20     memset(head,-1,sizeof(head));
21     memset(dfn,0,sizeof(dfn));
22     memset(low,0,sizeof(low));
23     memset(belo,0,sizeof(belo));
24 }
25 void add(int u,int v,int w){
26    edge[cnt].to=v;
27    edge[cnt].next=head[u];
28    edge[cnt].vis=0;
29    edge[cnt].w=w;
30    head[u]=cnt++;
31 }
32 void dfs(int u) {//可以处理重边的情况
33     low[u] = dfn[u] = ++time;
34     st[++top] = u;
35     for(int i = head[u];i != -1;i = edge[i].next) {
36         if(edge[i].vis)    continue;
37         edge[i].vis = edge[i^1].vis = 1;
38         int to = edge[i].to;
39         if(!dfn[to]) {
40             dfs(to);
41             low[u] = min(low[u], low[to]);
42             if(low[to] > dfn[u]) {//表示找到一个连通块
43                 type++;
44                 int v;
45                 do {
46                     v = st[top--];
47                     belo[v] = type;//表示v属于第type个连通块
48                 } while(v != to);
49                 geedge[++getot].u = u;//记录割边的起点
50                 geedge[getot].to = to;//记录割边的另一个点
51                 tval[getot]=edge[i].w;
52             }
53         }
54         else
55             low[u] = min(low[u], low[to]);
56     }
57 }
58 int main(){
59      while(~scanf("%d%d",&n,&m)&&n){
60          init();
61          for(int i=1;i<=m;i++){
62             scanf("%d%d %d",&u,&v,&w);
63             add(u,v,w);
64             add(v,u,w);
65          }
66          dfs(1);bool flag=false;
67          for(int i=1;i<=n;i++){
68             if(!dfn[i]){
69                 flag=true;
70                 break;
71             }
72          }
73          ans1=getot;ans=100000000;
74             for(int i=1;i<=ans1;i++){
75                 ans=min(ans,tval[i]);
76             }
77          if(ans==0)ans=1;
78          if(flag)ans=0;
79          if(!ans1&&!flag)printf("-1
");
80          else
81         printf("%d
",ans);
82      }
83 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3925507.html