差分约束
Posted 安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了差分约束相关的知识,希望对你有一定的参考价值。
1.bzoj3436
思路:
差分约束
根据限制条件建图,注意要有一个超级源点向所有点连一条边权为0的边
建图看代码。
然后spfa判负环,写bfs会超时的......实测n遍。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define inf 0x7fffffff #define ll long long #define N 100007 using namespace std; int n,m,cnt; int head[N],dis[N]; bool flag,ins[N]; struct edge { int to,next,v; } e[N]; void add(int u,int v,int w) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].v=w; } inline ll read() { ll x=0,f=1;char c=getchar(); while(c>‘9‘||c<‘0‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } void spfa(int x) { ins[x]=1; for(int i=head[x]; i; i=e[i].next) if(e[i].v+dis[x]>dis[e[i].to]) { if(ins[e[i].to]) { flag=1;return; } else { dis[e[i].to]=e[i].v+dis[x]; spfa(e[i].to); } } ins[x]=0; } bool check() { for(int i=1; i<=n; i++)dis[i]=ins[i]=0; flag=0; for(int i=1; i<=n; i++) { spfa(i); if(flag)return 1; } return 0; } int main() { n=read();m=read(); for(int i=1; i<=m; i++) { int f=read(); int a=read(),b=read(),c; if(f==1) { c=read(); if(a==b) {printf("No");return 0;} add(b,a,c); } else if(f==2) { c=read(); if(a==b) {printf("No");return 0;} add(a,b,-c); } else add(a,b,0),add(b,a,0); } for(int i=n; i>0; i--)add(0,i,1); if(check()) {printf("No");return 0;} printf("Yes"); return 0; }
以上是关于差分约束的主要内容,如果未能解决你的问题,请参考以下文章