【题解】HDU3592 World Exhibition

HDU3592 World Exhibition

因为求的是第一个数减去第n个数,所以我们让所有的差的形式都变为一个小的数减去一个大的数,从而使用差分约束系统。

有x个(a, b, c)

其中保证a < b

则b - a <= c

b <= a+c

造一个边 a连向b权值为c

最大距离最短路

有y个(p, q, w)

保证p < q

则q - p >= w

则q >= w + p,不好,-p >= w-q,p <= q-w,这个好

造一个边q 连向p, 权值为-w

最后跑带负边的单源最短路SPFS

代码后续改。。。以下为WAcode
#include <cmath>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int T, n, x, y, a, b, c; 
struct edge{
	int e, next, k;
}ed[22222];
int first[1010], en;
void add(int a, int b, int c){
	en++;
	ed[en].e = b;
	ed[en].k = c;
	ed[en].next = first[a];
	first[a] = en;
} 
//spfa
queue <int> q;//存点 
long long dist[1010];//到1的最短距离 
bool inque[1010];//是否在队 
int num[1010];//入队次数,判断是否有负环,负环输出,1
bool spfa(){
	while(q.size())		q.pop();
	memset(dist,0x3f,sizeof(dist));
	memset(inque,0,sizeof(inque));
	memset(num,0,sizeof(num));
	dist[1]=0;
	q.push(1);
	num[1]++; 
	while(q.size()){
		int now=q.front();
		q.pop();
		inque[now]=false;
		for(int e=first[now];e;e=ed[e].next ){
			int p=dist[now]+ed[e].k, old=ed[e].e;
			if(p < dist[old]){
				if(!inque[old]){
					inque[old]=true;
					q.push(old);
					num[old]++;
					if(num[old]>n){
						printf("-1\n");
						return 0;
					}
				}	
				dist[old]=p;
			}
		} 
	}
	if(dist[n]==0x3f){
		printf("-2\n");
		return 0;
	}
	printf("%d\n",dist[n]);
	return 1;
}
int main()
{
//	freopen("HDU3592World Exhibition.in","r",stdin);
	cin >> T;
	while(T--){
		//初始化
		memset(first,0,sizeof(first));
		en=0; 
		//读入部分 
		cin >> n >> x >> y;
		for(int i=1;i<=x;i++){
			cin>>a>>b>>c;
			if(a>b)	swap(a,b);//令a<b (其实不用。。。 
			add(a,b,c);//由a指向b 
		}
		for(int i=1;i<=y;i++){
			cin>>a>>b>>c;
			if(a>b)	swap(a,b);
			add(b,a,-c);//大的指向小的,权值-c 
		}
		//SPFA
		spfa(); 

	}
	return 0;
}

posted @ 2020-04-18 18:58  _Buffett  阅读(108)  评论(0编辑  收藏  举报