POJ 3259(最短路径)

题目链接:http://poj.org/problem?id=3259

题意:现在有n个点,m条边,w个虫洞,给出m个a,b,c,表示从a到b需要花费c时间,从b到a需要话费c时间,然后给出w个a,b,c,表示从a到b花费-c个时间,问是否存在一条路径使得最终回到源点的时间比初始时间小。

思路:最短路径,Bellman-Ford或SPFA判断是否存在负环的问题。

注意:数据范围比题目中给的略大一点,这点略坑。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=1010;
int T,n,m,w;
int dis[maxn];
int eNum;

struct Edge{
	int s;
	int e;
	int t;
}edge[10000];

void addEdge(int s,int e,int t){
	edge[eNum].s=s;
	edge[eNum].e=e;
	edge[eNum].t=t;
	eNum++;
}

bool Bellman_Ford(){
	for(int i=1;i<=n;i++)
		dis[i]=INF;
	dis[1]=0;
	for(int i=1;i<n;i++){
		for(int j=0;j<eNum;j++){
			if(dis[edge[j].e]>dis[edge[j].s]+edge[j].t){
				dis[edge[j].e]=dis[edge[j].s]+edge[j].t;
			}
		}
	}
	for(int k=0;k<eNum;k++){
		if(dis[edge[k].e]>dis[edge[k].s]+edge[k].t){
			return true;
		}
	}
	return false;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
#endif
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d",&n,&m,&w);
		eNum=0;
		int s,e,t;
		for(int i=0;i<m;i++){
			scanf("%d%d%d",&s,&e,&t);
			addEdge(s,e,t);
			addEdge(e,s,t);
		}
		for(int i=0;i<w;i++){
			scanf("%d%d%d",&s,&e,&t);
			addEdge(s,e,-t);
		}
		bool ans=Bellman_Ford();
		if(ans) puts("YES");
		else puts("NO");
	}
	return 0;
}


你可能感兴趣的:(POJ 3259(最短路径))