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;
}