Caocao's Bridges HDU - 4738

Caocao's Bridges

 HDU - 4738 
题意:一个带权无向图,破坏一条边的代价是权重,如果可以破坏一条边使得存在两点不能互达,输出最小代价。

 【找权值最小的桥】

找到桥更新答案即可。

注意如果本身图就不连通,则不需要破坏,代价为0

如果图不存在桥,则不满足输出-1

如果最后求出代价为0,则要输出1(因为题意是破坏桥,即使没有人守卫也要派一个人去炸桥)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int inf=0x3f3f3f3f;
 4 const int maxv=1000;
 5 int n,m;
 6 int ans;
 7 struct Edge
 8 {
 9     int v,w,nex;
10 }e[maxv*maxv<<1];
11 int head[maxv];
12 int cnt=0;
13 void init()
14 {
15     memset(head,-1,sizeof(head));
16     cnt=0;
17 
18     ans=inf;
19 }
20 void add(int u,int v,int w)
21 {
22     e[cnt].v=v;
23     e[cnt].w=w;
24     e[cnt].nex=head[u];
25     head[u]=cnt++;
26 }
27 
28 int pre[maxv],low[maxv],dfsk,bct;
29 
30 void Tarjin(int u,int id)
31 {
32     pre[u]=low[u]=++dfsk;
33     for(int i=head[u];i!=-1;i=e[i].nex)
34     {
35         int v=e[i].v;
36         if(i==(id^1)) continue;  //反向边
37         if(!pre[v])
38         {
39             Tarjin(v,i);
40             low[u]=min(low[u],low[v]);
41             if(low[v]>pre[u]&&ans>e[i].w) ans=e[i].w;
42         }
43         else low[u]=min(low[u],pre[v]);
44     }
45 }
46 
47 int main()
48 {
49     while(scanf("%d%d",&n,&m)&&(n||m))
50     {
51         init();
52         int u,v,w;
53         for(int i=0;i<m;i++)
54         {
55             scanf("%d%d%d",&u,&v,&w);
56             u--;v--;
57             add(u,v,w);
58             add(v,u,w);
59         }
60         memset(pre,0,sizeof(pre));
61         memset(low,0,sizeof(low));
62         dfsk=bct=0;
63         for(int i=0;i<n;i++) if(!pre[i])
64             bct++,Tarjin(0,-1);
65         if(bct>1) ans=0;
66         else if(ans==inf) ans=-1;
67         else if(ans==0) ans=1;
68         printf("%d\n",ans);
69 
70 
71     }
72 
73 }
View Code

 不用low数组,用dfs返回low值慢一些

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int inf=0x3f3f3f3f;
 4 const int maxv=1000;
 5 int n,m;
 6 int ans;
 7 struct Edge
 8 {
 9     int v,w,nex;
10 }e[maxv*maxv<<1];
11 int head[maxv];
12 int cnt=0;
13 void init()
14 {
15     memset(head,-1,sizeof(head));
16     cnt=0;
17 
18     ans=inf;
19 }
20 void add(int u,int v,int w)
21 {
22     e[cnt].v=v;
23     e[cnt].w=w;
24     e[cnt].nex=head[u];
25     head[u]=cnt++;
26 }
27 
28 int pre[maxv],dfsk,bct;
29 
30 int Tarjin(int u,int id)
31 {
32     int lowu=pre[u]=++dfsk;
33     for(int i=head[u];i!=-1;i=e[i].nex)
34     {
35         int v=e[i].v;
36         if(i==(id^1)) continue;  //反向边
37         if(!pre[v])
38         {
39             int lowv=Tarjin(v,i);
40             lowu=min(lowu,lowv);
41             if(lowv>pre[u]&&ans>e[i].w) ans=e[i].w;
42         }
43         else lowu=min(lowu,pre[v]);
44     }
45     return lowu;
46 }
47 
48 int main()
49 {
50     while(scanf("%d%d",&n,&m)&&(n||m))
51     {
52         init();
53         int u,v,w;
54         for(int i=0;i<m;i++)
55         {
56             scanf("%d%d%d",&u,&v,&w);
57             u--;v--;
58             add(u,v,w);
59             add(v,u,w);
60         }
61         memset(pre,0,sizeof(pre));
62         dfsk=bct=0;
63         for(int i=0;i<n;i++) if(!pre[i])
64             bct++,Tarjin(0,-1);
65         if(bct>1) ans=0;
66         else if(ans==inf) ans=-1;
67         else if(ans==0) ans=1;
68         printf("%d\n",ans);
69     }
70 }
View Code

 

posted @ 2017-08-18 16:16  yijiull  阅读(246)  评论(0编辑  收藏  举报