Caocao's Bridges
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1955 Accepted Submission(s): 699
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 <= N 2 )
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.
3 3 1 2 7 2 3 4 3 1 4 3 2 1 2 7 2 3 4 0 0
-1 4
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
#define maxn 1005
const int inf =0x3f3f3f3f;
struct edge
{
int v, w,rev, flag; //flag用于判断该边是否被访问过,rev代表反向边
edge(){};
edge(int vv, int ww, int rr){ v=vv; w=ww;rev=rr; flag=false;}
};
vector<edge> g[maxn];
int low[maxn],dfn[maxn], in[maxn];
int belong[maxn];
stack<int> s;
int n,m, dcc;
void init()
{
for(int i=0; i<maxn; i++)g[i].clear();
memset(dfn, 0, sizeof(dfn));
memset(in, 0, sizeof(in));
while(!s.empty()) s.pop();
dcc=0;
}
void add(int u, int v, int w)
{
g[u].push_back(edge(v, w, g[v].size()));
g[v].push_back(edge(u, w, g[u].size()-1));
}
void tarjan(int u, int &cnt, int &res)
{
dfn[u]=low[u]=++cnt;
s.push(u); in[u]=1;
int v;
for(int i=0; i<g[u].size(); i++){ //并不能通过检查v是否为u的父节点而跳过当前循环
v=g[u][i].v; //因为u,v间可能存在多条边,所以需要判断的是是否由同一条边访问回父节点,即同一条边不能来回两次遍历
if(!dfn[v]){
g[u][i].flag=true; g[v][g[u][i].rev].flag=true; //标记边访问过,防止同一条边的反向边再次访问
tarjan(v, cnt, res);
low[u]=min(low[v], low[u]);
if(low[v]>dfn[u]){
res=min(res, g[u][i].w);
}
}
else if(in[v] && !g[u][i].flag) {
low[u]=min(dfn[v], low[u]);
g[u][i].flag=true; g[v][g[u][i].rev].flag=true;
}
}
if(low[u]==dfn[u]){
dcc++;
do{
v=s.top(); s.pop();
belong[v]=dcc;
in[v]=false;
}while(v!=u);
}
}
int main()
{
while(scanf("%d%d", &n, &m)==2 && n+m!=0){
init();
int u,v,w;
for(int i=0; i<m; i++){
scanf("%d%d%d", &u, &v, &w);
add(u,v,w);
}
int tot=0, ans=inf;
tarjan(1, tot, ans);
if(ans==0) ans=1; //最小值为0也至少要派1个人去
for(int i=2; i<=n; i++) //原图不连通,ans=0
if(!dfn[i]){
ans=0;
break;
}
if(inf==ans) ans=-1;
printf("%d\n", ans);
}
return 0;
}
。
4254



被折叠的 条评论
为什么被折叠?



