1. 程式人生 > >差分約束(例題整理)

差分約束(例題整理)

整理 差分 stream 約束 -a http opened ace 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\n"); 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\n"); 92 continue; 93 } 94 u=min(a[1].pos,a[n].pos),v=max(a[1].pos,a[n].pos); 95 printf("%d\n",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 */
代碼實現

差分約束(例題整理)