1. 程式人生 > >poj 3169 layout

poj 3169 layout

nbsp print str 差分約束 main tex cstring 如果 namespace

POJ . 3169 Layout

鏈接:http://poj.org/problem?id=3169

題意 :

有N頭奶牛排隊餵食,它們之間有相互喜歡的,所以這兩頭相互喜歡的奶牛之間的距離要小於等於ML,同時,有相互討厭的的奶牛,它們之間的距離要大於等於MD,而且奶牛的位置和他們的標號順序相同,求奶牛1到奶牛N的最大距離,如果沒有最大距離輸出-1,最大距離無限大則-2;

這道題的思路是利用差分約束系統來建圖 :

如果u,v的最大距離為val :( 1 ) dis[ v ] - dis[ u ] < = val;

如果u,v的最小距離為val: ( 2 ) dis[ u ] - dis[ v ] < = - val;

又由於它們站位順序要與編號順序相同,所以說還需滿足:( 3 ) dis[ i ] - dis[ i - 1 ] > = 0;

由此我們就可以建圖了;

代碼:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

const int N = 2 * (1e6 + 1);
queue< int > q;
int tov[N],next[N],head[N],w[N],cnt[1001
],dis[N],tot,n,p,m; bool vis[1001]; void add(int u,int v,int val){ tot++; tov[tot] = v; next[tot] = head[u]; w[tot] = val; head[u] = tot; } int spfa(){ vis[1] = true; dis[1] = 0; q.push(1); cnt[1]++; while (!q.empty()){ int u = q.front(); q.pop(); for (int i = head[u];i;i = next[i]){
int v = tov[i]; if (dis[v] > dis[u] + w[i]){ dis[v] = dis[u] + w[i]; if (!vis[v]){ if ((++cnt[v]) > n) return -1; vis[v] = true; q.push(v); } } } vis[u] = false; } if (dis[n] == 1e9 + 7) return -2; return dis[n]; } int main(){ scanf("%d%d%d",&n,&p,&m); for (int i = 1;i <= n;i++) dis[i] = 1e9 + 7,add(i,i - 1,0); //滿足不等式3 for (int i = 1;i <= p;i++){ int u,v,d; scanf("%d%d%d",&u,&v,&d); add(u,v,d); //滿足不等式1 } for (int i = 1;i <= m;i++){ int u,v,d; scanf("%d%d%d",&u,&v,&d); add(v,u,-d); //滿足不等式2 } printf("%d",spfa()); return 0; }

poj 3169 layout