蓝书3.4 差分约束系统
Posted yyc-jack-0920
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝书3.4 差分约束系统相关的知识,希望对你有一定的参考价值。
T1 糖果 bzoj 2330
题目大意:
幼儿园里有N个小朋友,给这些小朋友们分配糖果,要求每个小朋友都要分到糖果 每个小朋友会提出一些要求
K行 每行输入三个数X A B
如果X=1, 表示第A个小朋友分到的糖果必须和第B个小朋友分到的糖果一样多
如果X=2, 表示第A个小朋友分到的糖果必须少于第B个小朋友分到的糖果
如果X=3, 表示第A个小朋友分到的糖果必须不少于第B个小朋友分到的糖果
如果X=4, 表示第A个小朋友分到的糖果必须多于第B个小朋友分到的糖果
如果X=5, 表示第A个小朋友分到的糖果必须不多于第B个小朋友分到的糖果
思路:
一道裸题
对于X=1的情况 在a b之间连无向边权值为0
X=2和X=4 在从a->b||b->a连有向边权值为1
X=3和X=5 在从b->a||a->b连有向边权值为0
如果有正环输出-1 开始的时候将所有点都放到队列里
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2147483647 10 #define ll long long 11 #define MAXN 100100 12 #define eps 1e-9 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 19 return x*f; 20 } 21 int n,m,q[MAXN<<4],l=1,r,f,st,inq[MAXN],num[MAXN]; 22 ll ans; 23 int to[MAXN<<1],nxt[MAXN<<1],fst[MAXN],dis[MAXN],val[MAXN<<1],cnt; 24 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;} 25 int spfa() 26 { 27 int x; 28 while(l<=r) 29 { 30 x=q[l++],inq[x]=0; 31 for(int i=fst[x];i;i=nxt[i]) 32 if(dis[to[i]]<dis[x]+val[i]) 33 { 34 dis[to[i]]=dis[x]+val[i]; 35 if(!inq[to[i]]) q[++r]=to[i],inq[to[i]]=1; 36 if(++num[to[i]]>=n) return 0; 37 } 38 } 39 return 1; 40 } 41 int main() 42 { 43 n=read(),m=read();int c,a,b; 44 while(m--) 45 { 46 c=read(),a=read(),b=read(); 47 if(c==1) {add(a,b,0);add(b,a,0);} 48 if(c==2) if(a!=b) add(a,b,1);else {puts("-1");return 0;} 49 if(c==3) add(b,a,0); 50 if(c==4) if(a!=b) add(b,a,1);else {puts("-1");return 0;} 51 if(c==5) add(a,b,0); 52 } 53 for(int i=1;i<=n;i++) dis[i]=1,inq[i]=1,num[i]=1,q[++r]=i; 54 if(!spfa()) {puts("-1");return 0;} 55 for(int i=1;i<=n;i++) ans+=dis[i]; 56 printf("%lld",ans); 57 } 58
T2 Layout bzoj 1731
题目大意:
数轴上放一些点 按顺序放n个点
有一些条件为 点a与点b的距离不大于或不小于一个距离c
思路:
还是裸题
因为按顺序放
所以不小于的情况就从a->b连权值为c的边 不大于的情况从b->a连权值为-c的边
判负环
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 100100 12 #define eps 1e-9 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 19 return x*f; 20 } 21 int n,m1,m2,q[MAXN<<4],l=1,r,f,st,inq[MAXN],num[MAXN]; 22 ll ans; 23 int to[MAXN<<1],nxt[MAXN<<1],fst[MAXN],dis[MAXN],val[MAXN<<1],cnt; 24 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;} 25 ll spfa() 26 { 27 q[++r]=1,dis[1]=0,num[1]=1;int x; 28 while(l<=r) 29 { 30 x=q[l++],inq[x]=0; 31 for(int i=fst[x];i;i=nxt[i]) 32 if(dis[to[i]]>dis[x]+val[i]) 33 { 34 dis[to[i]]=dis[x]+val[i]; 35 if(!inq[to[i]]) q[++r]=to[i],inq[to[i]]=1; 36 if(++num[to[i]]>=n) return -1; 37 } 38 } 39 if(dis[n]==inf) return -2; 40 return dis[n]; 41 } 42 int main() 43 { 44 n=read(),m1=read(),m2=read();int a,b,c; 45 while(m1--){a=read(),b=read(),c=read();add(a,b,c);} 46 while(m2--){a=read(),b=read(),c=read();add(b,a,-c);} 47 memset(dis,127,sizeof(dis)); 48 printf("%lld",spfa()); 49 }
以上是关于蓝书3.4 差分约束系统的主要内容,如果未能解决你的问题,请参考以下文章