標籤:namespace typedef ems http set style 方式 continue ++i
http://codeforces.com/problemset/problem/269/C
題目大意:
給定一個邊沒有定向的無法增廣的殘量網路且1是源點,n是匯點,給定每條邊中的流。?
讓你把所有邊定向的同時保證這是一個合法的無法增廣的無環殘量網路(n,m?<=2*10^5)
題解:
這道題首先從流量守恒的角度入手
我們知道對於每個中間點來說一定滿足流量守恒性質(流入量 == 流出量)
而我們又可以對所有相連的邊權加和求得所有(流入它)的和(流出的它的)流量之和
所以我們可以直接把相連的邊的權值之和加起來除以2,這樣就可以算出來它的流入量
相應的,我們就知道了它的流出量?
但是我們知道了所有邊的流入流出量有什麼用呢?
如果我們知道了一個點的所有的流入量,那我們是不是就可以知道剩下的邊一定是向外的呢?
答案是肯定的?
這時候我們想,要是每次我們都至少有一個點的流入都已知
那我就可以通過剩下的邊都流向外面的方式去更新剩餘的節點的流入量了
這種好事有沒有呢?
有!並且這樣的點在每次更新完後一定至少存在一個!?
所以我們直接使用類似於拓撲排序的過程來解決這道題就可以了!!!!
下面來證明這樣的點一定存在:
假設在幾次更新後(第一次一定存在,即源點1),不存在一個流入量已知的點,設其為u??
那麼我們知道,一定存在一條流??<x,u>是我們沒有成功定向的,所以說x也沒有定向!
這樣我們無限向前迭代,會出現兩種情況??
1.我們無限迭代後,回到了源點(x = 1)。??
這種情況下,我們知道如果x = 1那麼一定知道流<x,u>已經定向方向,矛盾,不成立.
2.我們無限迭代,一直處在一個迴圈裡。??
這種情況不可能發生。因為流網路中不可能存在環。所以這種情況也不成立????
所以兩種情況都不成立,故不存在這樣的點u??
所以,至少存在一個可更新的點,證明完畢
Code
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 typedef long long ll; 6 inline void read(int &x){ 7 x=0;char ch;bool flag = false; 8 while(ch=getchar(),ch<‘!‘);if(ch == ‘-‘) ch=getchar(),flag = true; 9 while(x=10*x+ch-‘0‘,ch=getchar(),ch>‘!‘);if(flag) x=-x;10 }11 inline int cat_max(const int &a,const int &b){return a>b ? a:b;}12 inline int cat_min(const int &a,const int &b){return a<b ? a:b;}13 const int maxn = 200010;14 struct Edge{15 int to,next,flow;16 bool flag;17 }G[maxn<<1];18 int head[maxn],cnt=1;19 inline void add(int u,int v,int c){20 G[++cnt].to = v;21 G[cnt].next = head[u];22 G[cnt].flow = c;23 head[u] = cnt;24 }25 int q[maxn],l,r,flow[maxn],n;26 #define v G[i].to27 inline void bfs(){28 l = 0;r = -1;q[++r] = 1;29 while(l <= r){30 int u = q[l++];31 for(int i = head[u];i;i=G[i].next){32 if(G[i].flag || G[i^1].flag) continue;33 G[i].flag = true;34 flow[v] -= G[i].flow;35 if(flow[v] == 0 && v != n) q[++r] = v;36 }37 }38 }39 #undef v40 int main(){41 int m;read(n);read(m);42 for(int i=1,u,v,d;i<=m;++i){43 read(u);read(v);read(d);44 add(u,v,d);add(v,u,d);45 flow[u] += d;flow[v] += d;46 }47 for(int i=1;i<=n;++i) flow[i] >>= 1;48 bfs();49 for(int i=2;i<=cnt;i+=2){50 printf("%d\n",G[i^1].flag);51 }52 getchar();getchar();53 return 0;54 }
CodeForces - 269C Flawed Flow