hdu 4005
http://acm.hdu.edu.cn/showproblem.php?pid=4005
思路:缩点之后形成一棵树,连任意两个点都能之后形成一个环,那么破坏这个环上的任意一个边都不会破坏图的连通性,我们只有破坏不在环上的边才能使图不连通。由于边是任意加的,我们当然要使最小的边尽量都在环里面。好了,这样的话我们可以先找一条最小边,因为如果最小边不在环里的话,那么破坏一个最小边就可以了。找到最小边了之后,以最小边的两个端点分别向两侧遍历一条路径,使得路径上的边的值都尽量小,也就是说使不在路径上的边的值的最小值尽量大,怎么做到呢?稍微想一下,在遍历的时候,对于每个点,他与各个儿子边的次小值(儿子边实际包含儿子子树上最小的边)的最小值就是答案,这样的话遍历两遍就好了。
ps:发现tarjan的写法有点不一样,如果按常规写,就wa。求解中~~~

#include<stdio.h> #include<string.h> #include<iostream> #include<stack> #include<algorithm> #include<utility> using namespace std; const int maxn = 10005; struct nd { int u,v,w,next; }edge[maxn*20]; int dfn[maxn],low[maxn],vis[maxn],head[maxn],belong[maxn]; int ecnt,cnt,idx,n,m,ans; int e[maxn*20][3],et; stack<int>st; void add(int s,int t,int w) { edge[ecnt].u = s; edge[ecnt].v = t; edge[ecnt].w = w; edge[ecnt].next = head[s]; head[s] = ecnt++; } void tarjan(int pre,int u) { int i,v; dfn[u] = low[u] = ++idx; st.push(u); for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(v==pre)continue; if(!dfn[v]) { tarjan(u,v); low[u] = min(low[u],low[v]); if(dfn[u]<low[v]) { e[++et][0] = u; e[et][1] = v; e[et][2] = edge[i].w; } }else low[u] = min(low[u],dfn[v]); } if(dfn[u]==low[u]) { cnt++; do{ v = st.top(); st.pop(); belong[v] = cnt; }while(v!=u); } } int dfs(int pre,int u) { int i,v; int m1=1e9,m2=1e9,r=1e9; for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(v==pre)continue; int w = dfs(u,v); if(w<m2) m2 = w; if(edge[i].w < m2) m2 = edge[i].w; if(m1>m2) swap(m1,m2); if(m1<r)r = m1; } if(ans>m2) ans = m2; return r; } int main() { int i,j,k,s,t,w; int ss,tt,ww; while(scanf("%d %d",&n,&m)==2) { memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); ecnt = 0; for(i = 0; i < m; ++ i) { scanf("%d %d %d",&s,&t,&w); add(s,t,w); add(t,s,w); } while(!st.empty()) st.pop(); cnt = idx = 0; et = 0; tarjan(0,1); k = ecnt; ecnt = 0; memset(head,-1,sizeof(head)); ww = 1e9; ss = tt = -1; for(i = 1; i <= et; ++ i) { s = e[i][0]; t = e[i][1]; w = e[i][2]; add(belong[s],belong[t],w); add(belong[t],belong[s],w); if(ww>w){ ss = belong[s]; tt = belong[t]; ww = w;} } ans = 1e9; if(ss!=-1){ dfs(ss,tt); dfs(tt,ss); } if(ans<1e9) printf("%d\n",ans); else puts("-1"); }return 0; }