线性约束
将所有不等式化成 \(d[a] - d[b] <= c\) 的形式,即有 \(a,b,c\)这条有向边,跑最短路即可
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const int N = 1e5+10;
const int inf = 0x3f3f3f3f;
struct E{
int u,v,nxt,w;
E(){}
E(int u,int v,int nxt,int w):u(u),v(v),nxt(nxt),w(w){}
}eg[N*3];
int head[N],cnt[N],vis[N],tot;
ll d[N];
void init(){
tot = 0 ; memset(head,-1,sizeof head);
}
void add(int u,int v,int w){
eg[++tot].u = u; eg[tot].v = v; eg[tot].w = w; eg[tot].nxt = head[u]; head[u] = tot;
}
int n,ml,md;
bool spfa(int s){
fill(d,d+n+1,inf);
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
queue<int> q;
q.push(s); d[s] = 0; vis[s] = 1;
while(q.size()){
int u = q.front(); q.pop();
vis[u] = 0;
for(int i=head[u];~i;i=eg[i].nxt){
int v = eg[i].v , w = eg[i].w;
if(d[v] > d[u] + w){
d[v] = d[u] + w;
cnt[v] = cnt[u] + 1;
if(cnt[v]>n){
return true;
}
if(!vis[v]){
vis[v] = 1;
q.push(v);
}
}
}
}
return false;
}
int main(){
int u,v,w;
init();
scanf("%d%d%d",&n,&ml,&md);
for(int i=1;i<=ml;++i){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
// add(v,u,w);
}
for(int i=1;i<=md;++i){
scanf("%d%d%d",&u,&v,&w);
add(v,u,-w); // 移项变号
}
for(int i=1;i<n;++i){
add(i+1,i,0); // 如果能重合就是0,不能重合就是-1
}
if(spfa(1)) puts("-1");
else if(d[n]==inf) puts("-2");
else printf("%lld\n",d[n]);
return 0;
}
原文地址:https://www.cnblogs.com/xxrlz/p/11617132.html
时间: 2024-10-07 15:30:21