Caocao's Bridges
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5576 Accepted Submission(s): 1751
In each test case:
The first line contains two integers, N and M, meaning that there are N islands and M bridges. All the islands are numbered from 1 to N. ( 2 <= N <= 1000, 0 < M <= N2 )
Next M lines describes M bridges. Each line contains three integers U,V and W, meaning that there is a bridge connecting island U and island V, and there are W guards on that bridge. ( U ≠ V and 0 <= W <= 10,000 )
The input ends with N = 0 and M = 0.
/**
無向圖,有重邊的情況找最小的橋
題解:要消除反向邊對其的影響,但是不能消除重邊對其的影響,
因爲存圖時是按照正向邊反向邊存的,所以第一次遇到v==fa的一定是因爲反向邊而存下來的
*/
#include<iostream>
#include<cstdio>
#include<vector>
#include<sstream>
#include<cstring>
#include<algorithm>
#define mem(a,x) memset(a,x,sizeof(a))
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1010;
struct node{
int v,w,id;
node(int v = 0,int w = 0,int id = 0):v(v),w(w),id(id){};
};
vector<node>G[N];
int pre[N];
int low[N];
int dfsLock;int ans ;int n,m;
void init(){
mem(pre,0); mem(low,0);
for(int i=0;i<=n;i++) G[i].clear();
dfsLock = 0;ans = INF;
}
int dfs(int u,int fa){
low[u] = pre[u] = ++dfsLock;
int k = 1;
for(int i=0;i<G[u].size();i++){
int v = G[u][i].v;
if(v == fa && k) {///沒有重邊則不需要這句話
k = 0;continue;
}
if(!pre[v]){
dfs(v,u);
low[u] = min(low[u],low[v]);///用後代的low更新當前的
if(low[v] > pre[u])
ans = min(ans,G[u][i].w);
}
else
low[u] = min(low[u],pre[v]);///利用後代v的反向邊更新low
}
}
int main(){
int t;
while(scanf("%d%d",&n,&m)!=EOF&& (n || m)){
int a,b,c;
init();
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
G[a].push_back(node(b,c,i));
G[b].push_back(node(a,c,i));
}
int cnt = 0;
for(int i=1;i<=n;i++){
if(!pre[i]){
cnt++;///連通圖的個數
dfs(i,-1);///根沒有父親,傳-1
}
}
if(cnt > 1) ///多於一個聯通分量 不用派人
ans = 0;
else if(ans == INF)
ans = -1;
else if(ans == 0) ///沒有人看守,也需要派一個人去炸橋
ans = 1;
printf("%d\n",ans);
}
return 0;
}