POJ 3169 Layout (差分约束入门)
Posted xxrlz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3169 Layout (差分约束入门)相关的知识,希望对你有一定的参考价值。
线性约束
将所有不等式化成 \(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;
以上是关于POJ 3169 Layout (差分约束入门)的主要内容,如果未能解决你的问题,请参考以下文章