题目:http://poj.org/problem?id=3259
AC代码(C++):
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>
#define INF 0xfffffff
using namespace std;
int map[505][505];
bool vis[505];
int cnt[505];
int num[505];
int N;
void spfa(){
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
memset(num,127,sizeof(num));
queue<int> Q;
Q.push(1);
vis[1]=1;
num[1]=0;
cnt[1]++;
while(!Q.empty()){
int tp=Q.front();
Q.pop();
vis[tp]=0;
if(cnt[tp]>=N){
cout<<"YES\n";
return;
}
for(int i=1;i<=N;i++){
if(i!=tp && map[tp][i]!=INF){
int t=num[tp]+map[tp][i];
if(t>=num[i]) continue;
num[i]=t;
if(!vis[i]) vis[i]=1,Q.push(i),cnt[i]++;
}
}
}
cout<<"NO\n";
}
int main(){
int f;
cin>>f;
for(int i = 0; i < f; i++){
memset(map,127,sizeof(map));
cin>>N;
int M,W;
cin>>M>>W;
for(int j = 0; j < M+W; j++){
int S,E,T;
cin>>S>>E>>T;
if(j<M&&T<map[S][E]){
map[S][E] = T;
map[E][S] = T;
}
else if(j>=M&&-T<map[S][E])map[S][E] = -T;
}
spfa();
}
}
总结:
1.找负环问题. 可以用bellman-ford或者spfa. 我这里用的spfa, 当一个节点入队超过N次时说明有负环.
2.这题要看清题目, 有几个地方有坑, 首先是path可以是双向的, 而且两个节点间可以有多条path, 但是不管怎样只有权值最小的那条才是有效的, 其他的忽略掉. wormhole的权值一定是负数所以可以覆盖path, 但是wormhole是单向的.