1. 程式人生 > >POJ 3169 C - Layout

POJ 3169 C - Layout

ostream ret view front iostream algorithm 排序 不能 set

題意

有n頭奶牛從1到n編號,按照編號順序站成一排,有可能有多頭奶牛站在同一個坐標上。一些奶牛互相喜歡,所以他們的距離不能大於某個距離,一些奶牛互相討厭,所以他們的距離不能小於某個距離,請計算如果可能的話1到n的最大距離是多少

分析

標準的差分約束的裸題。題中的條件可以做如下轉化

1.A和B的距離不得超過x: B-A<=x

2.C和D的距離不得小於y:C-D>=y也就是D-C<=-y

3.奶牛按照編號順序排序:位置 pos[i+1]-pos[i]>=0也就是pos[i]-pos[i+1]<=0

這樣把關系全部變成了小於關系,求最大距離的話建圖以後跑一個最短路就行。

技術分享圖片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <queue>
 6 
 7 using namespace std;
 8 const int maxn=1000+10;
 9 const int maxm=40000+10;
10 const int INF=2147000000;
11 
12 int head[maxn],Next[maxm],to[maxm],val[maxm];
13 int n,ml,md,sz; 14 void add_edge(int a,int b,int w){ 15 ++sz; 16 to[sz]=b; 17 val[sz]=w; 18 Next[sz]=head[a]; 19 head[a]=sz; 20 } 21 int a,b,w; 22 int spfa(){ 23 int d[maxn],vis[maxn],cnt[maxn]; 24 memset(vis,0,sizeof(d)); 25 memset(cnt,0,sizeof(cnt)); 26
for(int i=0;i<=n;i++)d[i]=INF; 27 queue<int>q; 28 q.push(n); 29 d[n]=0;vis[n]=1;cnt[n]=1; 30 while(!q.empty()){ 31 int u=q.front();q.pop();vis[u]=0; 32 // cout<<u<<endl; 33 for(int i=head[u];i;i=Next[i]){ 34 int v=to[i]; 35 if(d[v]>d[u]+val[i]){ 36 d[v]=d[u]+val[i]; 37 if(!vis[v]){ 38 vis[v]=1; 39 q.push(v); 40 cnt[v]++; 41 if(cnt[v]>n){ 42 return -1; 43 } 44 } 45 } 46 } 47 } 48 if(d[1]==INF) 49 return -2; 50 return d[1]; 51 } 52 int main(){ 53 scanf("%d%d%d",&n,&ml,&md); 54 for(int i=1;i<=ml;i++){ 55 scanf("%d%d%d",&a,&b,&w); 56 add_edge(b,a,w); 57 } 58 for(int i=1;i<=md;i++){ 59 scanf("%d%d%d",&a,&b,&w); 60 add_edge(a,b,-w); 61 } 62 for(int i=1;i<n;i++){ 63 add_edge(i,i+1,0); 64 } 65 int ans=spfa(); 66 printf("%d",ans); 67 68 return 0; 69 }
View Code

POJ 3169 C - Layout