差分约束模板
一道差分约束的吼题
对于此题,状态无非两种:基友与敌人
那么,就有u-v≤c 或者 u-v≥c
对于u-v≤c,可以用求最短路中的vis[v]=vis[u]+rood[i].s
我们对u−v≥c 转换成 v-u≤−c
这样,我们就可以很愉快的跑路啦
那么建图就酱:
#include<bits/stdc++.h>
using namespace std;
long long n,m,w;
long long a,b,c;
struct oppo {
long long to,s,next;
} rood[20004];
long long head[1005],tot;
void add(long long from,long long to,long long s) {
rood[++tot].s=s;
rood[tot].to=to;
rood[tot].next=head[from];
head[from]=tot;
}
long long vis[1004];
long long all[1004];
long long f[1004];
bool flag[1004];
stack< long long > v;
long long spfa(int x) {
memset(vis,10,sizeof(vis));
vis[x]=0;
v.push(x);
while(v.size()) {
long long lxl=v.top();
f[lxl]=0;
flag[lxl]=1;
v.pop();
for(long long i=head[lxl]; i; i=rood[i].next) {
if(vis[rood[i].to]>vis[lxl]+rood[i].s) {
vis[rood[i].to]=vis[lxl]+rood[i].s;
all[rood[i].to]=all[lxl]+1;
if(all[rood[i].to]>n)
return -1;
if(!f[rood[i].to]) {
f[rood[i].to]=1;
v.push(rood[i].to);
}
}
}
}
return vis[n]==vis[0]?-2:vis[n];
}
int main() {
cin>>n>>m>>w;
for(long long i=1; i<n; i++)
add(i+1,i,0);
for(long long i=1; i<=m; i++) {
scanf("%lld%lld%lld",&a,&b,&c);
add(a,b,c);
}
for(long long i=1; i<=w; i++) {
scanf("%lld%lld%lld",&a,&b,&c);
add(b,a,-c);
}
int ans,fff=0;
for(int i=1; i<=n; i++)
if(!flag[i]) {
ans=spfa(i);
if(fff) ans=ans==-1?-1:-2;
if(ans!=-2) break;
else fff=1;
}
cout<<ans<<endl;
return 0;
}