差分约束(例题整理)

Posted darkpurple

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了差分约束(例题整理)相关的知识,希望对你有一定的参考价值。

例题一:HDU 3440 

技术分享图片

 

样例输入:

3
4 4 
20 30 10 40 
5 6 
20 34 54 10 15 
4 2 
10 20 16 13 

 

样例输出:

Case 1: 3
Case 2: 3
Case 3: -1

 

技术分享图片
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<queue>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<algorithm>
  8 using namespace std;
  9 const int N=101000;
 10 const int inf=0x3f3f3f3f;
 11 
 12 int u,v,w,n,js,T,ha,cas;
 13 int head[N],dis[N],vis[N],s[N];
 14 queue<int > q;
 15 
 16 struct node {
 17     int nxt,v,val;
 18 }e[N];
 19 
 20 struct edge {
 21     int pos,w;
 22 }a[N];
 23 
 24 inline int read() {
 25     int n=0,f=1;char ch=getchar();
 26     while (ch<0 || ch>9) {if(ch==-) f=-1;ch=getchar();}
 27     while (ch<=9 && ch>=0) {n=(n<<3)+(n<<1)+ch-0;ch=getchar();}
 28     return n*f;
 29 }
 30 
 31 inline int cmp(edge x,edge y) {
 32     return x.w<y.w;
 33 }  
 34 
 35 inline void add_edge(int u,int v,int w) {
 36     e[++js].v=v,e[js].val=w;
 37     e[js].nxt=head[u],head[u]=js;
 38 }
 39 
 40 inline int spfa(int x,int t) {
 41     memset(dis,0x3f,sizeof(dis));
 42     memset(vis,0,sizeof(vis));
 43     memset(s,0,sizeof(s));
 44     
 45     dis[x]=0,vis[x]=1;
 46     q.push(x),s[x]++;
 47     
 48     while (!q.empty()) {
 49         int u=q.front();
 50         q.pop();
 51         vis[u]=0;
 52         for(int i=head[u];i;i=e[i].nxt) {
 53             int v=e[i].v;
 54             if(dis[v]>dis[u]+e[i].val) {
 55                 dis[v]=dis[u]+e[i].val;
 56                 if(!vis[v]) {
 57                     s[v]++;
 58                     vis[v]=1,q.push(v);
 59                     if(s[v]>n) { 
 60                         printf("-1
"); 
 61                         exit(0);
 62                     }
 63                 }
 64             }
 65         }
 66     }
 67     return dis[t];
 68 }
 69 
 70 inline int build () {
 71     sort(a+1,a+n+1,cmp);
 72     memset(e,0,sizeof(e));
 73     for(int i=1;i<n;++i) {
 74         add_edge(i+1,i,-1);
 75         int u=min(a[i].pos,a[i+1].pos);
 76         int v=max(a[i].pos,a[i+1].pos);
 77         int w=abs(a[i].pos-a[i+1].pos);
 78         if(w>ha) return 0;
 79         add_edge(u,v,ha);
 80     }
 81     return 1;
 82 }
 83 
 84 int main() {
 85     T=read();
 86     while (T--) {
 87         n=read(),ha=read();cas++;
 88         for(int i=1;i<=n;++i) a[i].w=read(),a[i].pos=i;
 89         printf("Case %d: ",cas);
 90         if(!build()) {
 91             printf("-1
");
 92             continue;
 93         }
 94         u=min(a[1].pos,a[n].pos),v=max(a[1].pos,a[n].pos);
 95         printf("%d
",spfa(u,v));
 96     }
 97     return 0;
 98 }
 99 
100 /*
101 3
102 4 4
103 20 30 10 40
104 5 6
105 20 34 54 10 15
106 4 2
107 10 20 16 13
108 */
代码实现

以上是关于差分约束(例题整理)的主要内容,如果未能解决你的问题,请参考以下文章

差分拘束介绍总结与例题

浅谈差分约束系统

差分约束讲解

差分约束

查分约束例题(洛古)

浅谈差分约束系统