题目
思路
很明显的差分约束板子
- 如果需要求的是两个变量差的最大值,那么需要将所有不等式转变成<=的形式,建图后求最短路;
- 如果需要求的是两个变量差的最小值,那么需要将所有不等式转化成>=,建图后求最长路。
本题需要建超级原点使图联通,判掉不合法情况 - 图中有负环不能到达
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+10;
const int maxm=5000*10+10;
int n,m,k;
int head[maxn],ver[maxm],edge[maxm],Next[maxm],tot;
void add(int x,int y,int z){
ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
}
int dis[maxn];
bool vis[maxn];
bool flag=0;
int cnt[maxn];
queue<int>q;
int spfa(int x){
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[x]=0;vis[x]=1;q.push(x);cnt[x]++;
while(!q.empty()){
int u=q.front();q.pop();vis[u]=0;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(dis[v]>dis[u]+edge[i]){
dis[v]=dis[u]+edge[i];
if(!vis[v]){
cnt[v]++;
if(cnt[v]>n+1)return -1;
vis[v]=1;
q.push(v);
}
}
}
}
if(dis[n]==0x3f3f3f3f)return -2;
return dis[n];
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1,x,y,z;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
if(x>y)swap(x,y);
add(x,y,z);
}
for(int i=1,x,y,z;i<=k;i++){
scanf("%d%d%d",&x,&y,&z);
if(x>y)swap(x,y);
add(y,x,-z);
}
for(int i=1;i<=n;i++){
add(0,i,0);
}
for(int i=1;i<n;i++){
add(i+1,i,0);
}
if(spfa(0)==-1){
printf("-1
");
return 0;
}
printf("%d
",spfa(1));
}