UVA 11478 Halum (差分约束)
生活随笔
收集整理的這篇文章主要介紹了
UVA 11478 Halum (差分约束)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2473
?
題解:
?首先我們可以得到的約束條件形如 xi - xj <= b[k] ,即可以轉換為 j - > i連邊,且權值為b[k],這樣建圖后我們判斷是否有解,只需要用spfa跑負圈就可以了.
?如果存在負圈,原差分系統定然無解.
?簡單證明:
?我們不妨設這個環為 x1,x2...xn
?即有不等式 x1 <= x2 + y1 , x2 <= x3 + y2 ..... xn <= x 1 + yn
?全部累加得 0 <= sigma (y)
?所以有解必須滿足sigma(y) >= 0 ,如果存在負圈,肯定是無解的.
?那么對于原圖,如何判斷infinate的情況呢?
?注意到約束條件必須是環,所以我們只需要檢測一下圖中是否有環就可以了.
?
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn = 5e2 + 50; const double eps = 1e-6; struct Edge{int v , nxt , w;}; Edge e[maxn * 6]; int n , m , head[maxn] , tot , cnt[maxn] ,inq[maxn] ,d[maxn],c[maxn]; queue<int>q; void addedge(int u,int v,int w){e[tot].v=v,e[tot].nxt=head[u],e[tot].w=w,head[u]=tot++;}void edge_init(int x) {for(int i = 0 ; i < tot ; ++ i) e[i].w += x; }bool check() {while(!q.empty()) q.pop();memset(cnt , 0 , 4 * (n + 1));memset( d , 0 , 4 * (n + 1) );for(int i = 1 ; i <= n ; ++ i){inq[i] = 1;q.push(i);}while(!q.empty()){int x = q.front();q.pop();inq[x]=0;for(int i = head[x] ; ~i ; i = e[i].nxt){int v = e[i].v;double neww = d[x] + e[i].w;if(neww < d[v]){d[v] = neww;if(!inq[v]){inq[v] = 1;if(++cnt[v] > n) return true;q.push(v);}}}}return false; }bool dfs(int u) {c[u]=-1;for(int i = head[u] ; ~i ; i = e[i].nxt){int v = e[i].v;if(c[v]==1) continue;if(c[v]==-1) return true;if(dfs(v)) return true;}c[u]=1;return false; }int main(int argc,char *argv[]) {while(~scanf("%d%d",&n,&m)){memset(head,-1,4*(n+1));tot=0;memset(c , 0 , 4 * (n + 1));for(int i = 0 ; i < m ; ++ i){int u ,v,w ;scanf("%d%d%d",&u,&v,&w);addedge( u , v, w);}int flag = 0;for(int i = 1 ; i <= n ; ++ i)if(c[i]==0)if(dfs(i)){flag=1;break;}if(!flag){printf("Infinite\n");continue;}int L = 0 , R = 20000;while(L < R){int mid = L + (R-L+1)/2;edge_init(-mid);if(check()) R = mid-1;else L = mid;edge_init(mid);}edge_init(-L);if(L == 0 || check()) printf("No Solution\n");else printf("%d\n",L);}return 0; }?
轉載于:https://www.cnblogs.com/Xiper/p/4900381.html
總結
以上是生活随笔為你收集整理的UVA 11478 Halum (差分约束)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Palindrome Partition
- 下一篇: poj_2739 尺取法