題目大意:
當排隊等候餵食時,奶牛喜歡和它們的朋友站得靠近些。fj有n(2<=n<=1000)頭奶牛,編號從1到n,沿一條直線站著等候喂
食。奶牛排在隊伍中的順序和它們的編號是相同的。因為奶牛相當苗條,所以可能有兩頭或者更多奶牛站在同一位置上。即使說,
如果我們想象奶牛是站在一條數軸上的話,允許有兩頭或更多奶牛擁有相同的橫座標。
一些奶牛相互間存有好感,它們希望兩者之間的距離不超過乙個給定的數l。另一方面,一些奶牛相互間非常反感,它們希望兩者間
的距離不小於乙個給定的數d。給出ml條關於兩頭奶牛間有好感的描述,再給出md條關於兩頭奶牛間存有反感的描述。
(1<=ml,md<=10000,1<=l,d<=1000000)
你的工作是:如果不存在滿足要求的方案,輸出-1;如果1號奶牛和n號奶牛間的距離可以任意大,輸出-2;否則,計算出在滿足所
有要求的情況下,1號奶牛和n號奶牛間可能的最大距離。
演算法思想:
我們先研究,如果不要求輸出1和n的最大距離,而只需乙個可行的距離,應該如何操作。
我們用d[i]表示i號奶牛和1號奶牛間的距離。
因為在隊伍中的順序必須和編號相同,所以對於任意i號奶牛,1<=i
d[i+1] - d[i] >= 0
對於每個好感的描述(i,j,k),假設i<=j,體現到距離上的要求就是:
d[j] - d[i] <= k
對於每個反感的描述(i,j,k),假設i<=j,體現到距離上的要求就是:
d[j] - d[i] >= k
這時的模型有乙個名稱,叫作:差分約束系統。
為了方便起見,我們將每種不等式寫成我們約定的形式:
d[i] <= d[i+1]
d[j] <= d[i] + k
d[i] <= d[j] - k
看到這些不等式,你想到了什麼?
沒錯,在求頂點間地最短路問題中,我們有這樣的不等式:
若頂點u到頂點v有邊e=uv,且邊權為w(e),設d(u),d(v)為源點到頂點u和頂點v的最短路長,
則 d(v) <= d(u) + w(e)
這個不等式和前面的條件形式十分相似,這就啟發我們用構圖用最短路做。
具體步驟是:
作有向圖g=(v,e),v=,e=,對於相鄰兩點i和(i+1),對應的頂點vi+1向vi引一條邊,費用
為0;對於每組好感描述(ai,bi,di),我們假設有ai
(ai,bi,di),我們假設有ai
於是問題變為在g中求v1到其它所有頂點的最短路。我們證明若g中無負權迴路,則問題有解,即存在滿足條件的數列,若g中有負
權迴路,則問題無解,即不存在滿足條件的數列。
#include #include #include #include #include #define inf 0xfffffff
using namespace std;
const int v=1010;
const int e=20010;
int n,ml,md;
int pnt[e],cost[e],nxt[e];
int e,head[v],dis[v];
int vis[v];
int cnt[v];
int relax(int u,int v,int c)
return 0;
}inline void addedge(int u,int v,int c)
int spfa(int src,int n)}}
if(dis[n] == inf)
return -2;
return dis[n];
}int main()
for(int i = 0; i < md; ++i)
printf("%d\n",spfa(1,n));
}return 0;
}
POJ3169 Layout 差分約束)
題意 一堆牛在一條直線上按編號站隊,在同一位置可以有多頭牛並列站在一起,但編號小的牛所佔的位置不能超過編號大的牛所佔的位置,這裡用d i 表示編 號為i的牛所處的位置,即要滿足d i d i 1 0,同時每兩頭牛之間有以下兩種關係 對於輸入的a b d來說 1 如果是喜歡關係 即需要滿足d b d ...
POJ3169 Layout 差分約束
題目鏈結。分析 對於任意i號奶牛,1 id i 1 d i 0 對於每個好感的描述 i,j,k 假設i j,體現到距離上的要求就是 d j d i k 對於每個反感的描述 i,j,k 假設i j,體現到距離上的要求就是 d j d i k 寫成我們約定的形式 d i d i 1 0 d j d i ...
POJ 3169 Layout 差分約束
題意 有n頭牛,這些牛都擁有乙個屬性x表示其在座標軸上的座標。現在給定ml組約束條件表示a b兩頭牛座標之差不能夠超過c md組約束條件表示a b兩頭牛座標之差不能小於c,現在問1和n號牛之間最長的距離為多大,如果存在則輸出最大長度,如果任意輸出 2,如果已知條件存在矛盾輸出 1。解法 根據已知條件...