【BZOJ2095】[Poi2010]Bridges 動態加邊網絡流
阿新 • • 發佈:2017-11-05
mage ems output string get 之間 一行 ++ cpp
1 2 2 4
2 3 3 4
3 4 4 4
4 1 5 4
【BZOJ2095】[Poi2010]Bridges
Description
YYD為了減肥,他來到了瘦海,這是一個巨大的海,海中有n個小島,小島之間有m座橋連接,兩個小島之間不會有兩座橋,並且從一個小島可以到另外任意一個小島。現在YYD想騎單車從小島1出發,騎過每一座橋,到達每一個小島,然後回到小島1。霸中同學為了讓YYD減肥成功,召喚了大風,由於是海上,風變得十分大,經過每一座橋都有不可避免的風阻礙YYD,YYD十分ddt,於是用泡芙賄賂了你,希望你能幫他找出一條承受的最大風力最小的路線。
Input
輸入:第一行為兩個用空格隔開的整數n(2<=n<=1000),m(1<=m<=2000),接下來讀入m行由空格隔開的4個整數a,b(1<=a,b<=n,a<>b),c,d(1<=c,d<=1000),表示第i+1行第i座橋連接小島a和b,從a到b承受的風力為c,從b到a承受的風力為d。
Output
輸出:如果無法完成減肥計劃,則輸出NIE,否則第一行輸出承受風力的最大值(要使它最小)
Sample Input
4 41 2 2 4
2 3 3 4
3 4 4 4
4 1 5 4
Sample Output
4題解:混合圖歐拉回路做法:先將所有邊隨意定向,然後從S向所有度數為正的點連邊,度數為負的點向T連邊,再連上原圖的反向邊,跑最大流看是否有解即可。
對於本題,我們可以先對於每條邊選取阻力較小的那個方向,然後將按另一個方向的阻力排序,從小到大扔到圖中,如果扔進去之後滿流了,則輸出答案即可。
網上部分用二分做的代碼有問題,可以被hack。
#include <cstdio> #include <cstring> #include <iostream> #include <queue> #include <algorithm> using namespace std; int n,m,ans,sum,cnt,S,T; struct node { int a,b,c,d; }p[2010]; int to[10010],next[10010],val[10010],head[1010],d[1010]; queue<int> q; bool cmp(const node &a,const node &b) { return a.d<b.d; } inline void add(int a,int b,int c) { to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++; to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++; } int dfs(int x,int mf) { if(x==T) return mf; int i,k,temp=mf; for(i=head[x];i!=-1;i=next[i]) if(d[to[i]]==d[x]+1&&val[i]) { k=dfs(to[i],min(temp,val[i])); if(!k) d[to[i]]=0; val[i]-=k,val[i^1]+=k,temp-=k; if(!temp) break; } return mf-temp; } int bfs() { memset(d,0,sizeof(d)); while(!q.empty()) q.pop(); int i,u; q.push(S),d[S]=1; while(!q.empty()) { u=q.front(),q.pop(); for(i=head[u];i!=-1;i=next[i]) if(!d[to[i]]&&val[i]) { d[to[i]]=d[u]+1; if(to[i]==T) return 1; q.push(to[i]); } } return 0; } inline int rd() { int ret=0,f=1; char gc=getchar(); while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘) f=-f; gc=getchar();} while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+(gc^‘0‘),gc=getchar(); return ret*f; } int main() { n=rd(),m=rd(); int i; for(i=1;i<=m;i++) { p[i].a=rd(),p[i].b=rd(),p[i].c=rd(),p[i].d=rd(); if(p[i].c>p[i].d) swap(p[i].a,p[i].b),swap(p[i].c,p[i].d); d[p[i].a]++,d[p[i].b]--; ans=max(ans,p[i].c); } sort(p+1,p+m+1,cmp); memset(head,-1,sizeof(head)); S=0,T=n+1; for(i=1;i<=n;i++) { if(d[i]&1) { printf("NIE"); return 0; } d[i]>>=1; if(d[i]>0) add(S,i,d[i]),sum+=d[i]; if(d[i]<0) add(i,T,-d[i]); } if(sum) for(i=1;i<=m;i++) { add(p[i].a,p[i].b,1); ans=max(ans,p[i].d); while(bfs()) sum-=dfs(S,1<<30); if(!sum) break; } if(sum) printf("NIE"); else printf("%d",ans); return 0; }
【BZOJ2095】[Poi2010]Bridges 動態加邊網絡流