链接:http://acm.hdu.edu.cn/showproblem.php?pid=4005
题意是说,在一个无向带权图中可以在原来没有直接相连的两个点上加一条边,然后要求你删去一条边,要求得出无论对方加的是哪一条边,你都可以删除一条<=v的边导致这个图不连通,要找出最小的V是多少。
分析:首先,对于图中的双连通分量来说,删除其中的边是没有任何意义的,所以先进行缩点
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define N 20005 5 #define M 200005 6 #define inf 0x7fffffff 7 using namespace std; 8 int head[N],head1[N],cnt,cnt1,dp[N]; 9 struct node 10 { 11 int u,v,next,w; 12 }; 13 node e[2*M],e1[2*M]; 14 int Ti[N],ti,low[N],bel[N]; 15 bool used[N],flag; 16 int cnt2,stk[N],top,insta[N]; 17 int ans,a,b; 18 int min(int a,int b) 19 { 20 return a<b?a:b; 21 } 22 void init() 23 { 24 memset(head,-1,sizeof(head)); 25 memset(head1,-1,sizeof(head1)); 26 memset(used,0,sizeof(used)); 27 memset(low,0,sizeof(low)); 28 memset(bel,0,sizeof(bel)); 29 memset(Ti,0,sizeof(Ti)); 30 memset(insta,0,sizeof(insta)); 31 cnt=cnt1=ti=top=cnt2=0; 32 } 33 void add(int u,int v,int w) 34 { 35 e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;e[cnt].next=head[u]; 36 head[u]=cnt++; 37 e[cnt].u=v;e[cnt].v=u;e[cnt].w=w;e[cnt].next=head[v]; 38 head[v]=cnt++; 39 } 40 void add1(int u,int v,int w) 41 { 42 e1[cnt1].u=u,e1[cnt1].v=v,e1[cnt1].w=w,e1[cnt1].next=head1[u]; 43 head1[u]=cnt1++; 44 } 45 void tarjan(int u,int rt) 46 { 47 Ti[u]=low[u]=++ti; 48 stk[++top]=u; 49 insta[u]=true; 50 int i,j,v; 51 for(i=head[u];i>=0;i=e[i].next) 52 { 53 v=e[i].v; 54 if(v==rt) 55 continue; 56 if(!Ti[v]) 57 { 58 tarjan(v,u); 59 low[u]=min(low[u],low[v]); 60 } 61 else if(insta[v]) 62 low[u]=min(low[u],Ti[v]); 63 } 64 if(Ti[u]==low[u]) 65 { 66 cnt2++; 67 do 68 { 69 j=stk[top--]; 70 bel[j]=cnt2; 71 insta[j]=false; 72 }while(u!=j); 73 } 74 } 75 void dfs(int u) 76 { 77 int v,i,j; 78 used[u]=true; 79 for(i=head1[u];i>=0;i=e1[i].next) 80 { 81 v=e1[i].v; 82 if(used[v]) 83 continue; 84 dfs(v); 85 dp[v]=min(dp[v],e1[i].w); 86 if(dp[u]>dp[v]) 87 { 88 ans=min(dp[u],ans); 89 dp[u]=dp[v]; 90 } 91 else 92 ans=min(ans,dp[v]); 93 } 94 } 95 void creat(int n) 96 { 97 int i,j,u,v; 98 for(i=1;i<=n;i++) 99 if(!Ti[i]) 100 tarjan(i,-1); 101 int minn=inf; 102 if(cnt2==1) 103 { 104 flag=false; 105 return; 106 } 107 for(i=0;i<cnt;i++) 108 { 109 if(bel[e[i].u]!=bel[e[i].v]) 110 { 111 add1(bel[e[i].u],bel[e[i].v],e[i].w); 112 if(e[i].w<minn) 113 { 114 minn=e[i].w; 115 a=bel[e[i].u]; 116 b=bel[e[i].v]; 117 } 118 } 119 } 120 } 121 int main() 122 { 123 int n,m,i,j,u,v,w; 124 while(scanf("%d%d",&n,&m)!=EOF) 125 { 126 init(); 127 while(m--) 128 { 129 scanf("%d%d%d",&u,&v,&w); 130 add(u,v,w); 131 } 132 flag=true; 133 creat(n); 134 if(!flag) 135 { 136 printf("-1\n"); 137 continue; 138 } 139 for(i=0;i<=n;i++) 140 dp[i]=inf; 141 ans=inf; 142 used[a]=used[b]=true; 143 dfs(a); 144 dfs(b); 145 if(ans==inf) 146 printf("-1\n"); 147 else 148 printf("%d\n",ans); 149 } 150 return 0; 151 }