hdu 4005 边双联通

题意:

有一幅图,现在要加一条边,加边之后要你删除一条边,使图不连通,费用为边的费用,要你求的是删除的边的最小值的最大值(每次都可以删除一条边,选最小的删除,这些最小中的最大就为答案)

首先要进行缩点,把图缩为一棵树,因此,加入一条边后图就会存在一个环,环中的任何一条边删除后都不会导致图不连通

之后找一条最小的边,可以说这条边肯定是在加边之后的连通块里的,因为如果不在连通块里,那就直接可以把这条最小的边删掉,而达不到求出答案的目的

找到边后,分别从边的两点开始遍历,要遍历出一条路径来,并且边上的权值要尽可能的小,因为这样才能让不在环中的边尽可能的大,然后,答案就是每个节点的次小儿子的最小值,如果没有次小儿子就不能算(就是说只有一个儿子,即节点不是三叉的),因为我完全可以把它和最小的边放到一个连通块中,那样答案就应该更大了。

终上所述:先进行无向图的缩点,再在树上找最小的边,最后分别从边的两点出发,遍历树,找节点的次小儿子节点中的最小值

举个简单的例子(括号内的数字代表边上的权值)1和8间的权值为1,是最小的

                     1---8

                  /           \(3) 

        (2)/               \

             2                  3

    (4) /       \(5)    (6)/      \(7)

       /           \         /          \

     4              5     6              7

左子树中2的子节点有次小值5,右子树中3的子节点次小值为7,两个次小值间的最小值是5,即答案

现在,比如所你要把3、4连起来。我可以去掉2、5之间的边让图不连通,花费为5

把3、5连起来,我自然可以删掉2、4,花费为4,

一个节点的次小值和最小值(比如说4、5两点)不可能被同时连进一个连通块(或环)中(因为必须把最小的那条边加进环中),正是利用这个性质,不管把那两个点连起来,我们都可以找到一个最小值或次小值来删掉使图不连通,注意:再重复一遍,同一个节点的最小值和次小值不会被加进同一个环,因此,这些次小值中的最小的那条边的权值就是答案。(这时你如果把次小的边加进环中,如2--5,自然可以删掉一条更小的边 如2--4 使图不连通,相反,如果没有把次小的边加进去,那次小的就是答案)

还是蛮难想的。。。昨天搞了一下午额*_*,最后还是受了点播才。。。。。

View Code
  1 #include<stdio.h>
2 #include<string.h>
3 #include<vector>
4 #include<algorithm>
5 #include<iostream>
6 using namespace std;
7 const int maxn = 10010;
8 int tot,n,m,ans;
9 const int inf = 999999999;
10 struct Edge
11 {
12 int t,w;
13 int next;
14 int vis;
15 }edge[1000005];
16 int head[maxn],E;
17 void add(int s,int t,int w)
18 {
19 edge[E].t=t;
20 edge[E].w=w;
21 edge[E].vis=0;
22 edge[E].next=head[s];
23 head[s]=E++;
24 }
25 int Btype,Time,N,M;
26 int dfn[maxn],low[maxn],belong[maxn];
27 int st[maxn],Top;
28 int tt[100010][3],cnt;
29 inline int min(int a,int b){return a<b?a:b;}
30 void dfs(int s)
31 {
32 int i,t;
33 st[++Top]=s;
34 dfn[s]=low[s]=++Time;
35 for (i=head[s];i!=-1;i=edge[i].next)
36 {
37 if(edge[i].vis)continue;
38 edge[i].vis=edge[i^1].vis=1;
39 t=edge[i].t;
40 if (!dfn[t])
41 {
42 dfs(t);
43 low[s]=min(low[s],low[t]);
44 if(dfn[s]<low[t])
45 {
46 //printf("bug");
47 tt[++cnt][0]=s,tt[cnt][1]=t,tt[cnt][2]=edge[i].w;
48 }
49 }
50 else low[s]=min(low[s],dfn[t]);
51 }
52 if(dfn[s]==low[s])
53 {
54 Btype++;
55 do{
56 t=st[Top--];
57 belong[t]=Btype;
58 }while(t!=s);
59 }
60 }
61 void SCC(int n)
62 {
63 int i;
64 Time=0;Btype=0;Top=0;
65 memset(dfn,0,sizeof(int)*(n+1));
66 for(i=1;i<=n;i++)if(!dfn[i])
67 dfs(i);
68 }
69 int find(int s,int t)
70 {
71 int i;
72 int Min=inf,vice_Min=inf,rr=inf;
73 for(i=head[s];i!=-1;i=edge[i].next)
74 {
75 int v=edge[i].t;
76 if(v==t) continue;
77 int w=find(v,s);//printf("w=%d\n",w);
78 if(w<vice_Min) vice_Min=w;
79 if(edge[i].w<vice_Min) vice_Min=edge[i].w;
80 if(Min>vice_Min) swap(vice_Min,Min);
81 if(Min<rr) rr=Min;
82 }
83 if(ans>vice_Min) ans=vice_Min;
84 return rr;
85 }
86 int a1,a2,flag;
87 int main()
88 {
89 int i,a,b,w;
90 while(scanf("%d%d",&n,&m)!=EOF)
91 {
92 memset(head,-1,sizeof(head));E=0;
93 for(i=0;i<m;i++)
94 {
95 scanf("%d%d%d",&a,&b,&w);
96 add(a,b,w);
97 add(b,a,w);
98 }
99 cnt=0;
100 SCC(n);
101 memset(head,-1,sizeof(head));E=0;
102 int C=inf;
103 for(i=1;i<=cnt;i++)
104 {
105 // printf("s=%d t=%d\n",tt[i][0],tt[i][1]);
106 add(belong[tt[i][0]],belong[tt[i][1]],tt[i][2]);
107 add(belong[tt[i][1]],belong[tt[i][0]],tt[i][2]);
108 if(tt[i][2]<C){C=tt[i][2]; a=belong[tt[i][0]],b=belong[tt[i][1]];}
109 }
110 ans=inf;
111 find(a,b);
112 find(b,a);
113 if(ans==inf) printf("-1\n");
114 else printf("%d\n",ans);
115 }
116 return 0;
117 }
118 /*
119 7 6
120 1 2 2
121 1 3 6
122 2 4 3
123 2 5 4
124 3 6 5
125 3 7 7
126 4
127 15 14
128 1 2 7
129 2 4 5
130 2 5 6
131 4 8 1
132 4 9 2
133 5 10 3
134 5 11 4
135 1 3 8
136 3 6 9
137 3 7 1
138 6 12 11
139 6 13 12
140 7 14 13
141 7 15 14
142 2
143 16 15
144 1 2 7
145 2 4 5
146 2 5 6
147 4 8 1
148 4 9 2
149 5 10 3
150 5 11 4
151 1 16 1
152 16 3 6
153 3 6 9
154 3 7 1
155 6 12 11
156 6 13 12
157 7 14 13
158 7 15 14
159 2
160 6 5
161 1 2 1
162 1 3 2
163 1 4 3
164 2 5 4
165 2 6 5
166 3
167 9 8
168 1 2 1
169 2 6 5
170 6 7 7
171 6 8 4
172 6 9 6
173 1 3 2
174 1 4 5
175 1 5 6
176 5
177 9 8
178 1 2 1
179 2 6 5
180 6 7 7
181 6 8 4
182 6 9 4
183 1 3 2
184 1 4 5
185 1 5 6
186 4*/



posted @ 2011-11-04 09:39  Because Of You  Views(1270)  Comments(0Edit  收藏  举报