题目大意:给定一张图,每条边的两个方向有两个不同的权值,现在要求从1号节点出发遍历每条边一次且仅一次,最后回到1号节点,求最大边权的最小值
谁TM翻译的这道题给我滚出来看我不打死你
二分最大边的权值,然后就是经典的判断混合图欧拉回路存在性的问题了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 2020 #define S 0 #define T 2019 #define INF 0x3f3f3f3f using namespace std; struct edge{ int x,y,z1,z2; }edges[M]; int n,m,max_num; namespace Euler_Circuit{ namespace Union_Find_Set{ int fa[M],size[M],cnt; void Initialize() { memset(fa,0,sizeof fa); cnt=n; } int Find(int x) { if(!fa[x]) fa[x]=x,size[x]=1; if(fa[x]==x) return x; return fa[x]=Find(fa[x]); } void Union(int x,int y) { x=Find(x);y=Find(y); if(x==y) return ; if(size[x]>size[y]) swap(x,y); fa[x]=y;size[y]+=size[x]; cnt--; } } namespace Max_Flow{ struct abcd{ int to,f,next; }table[1001001]; int head[M],tot=1; int dpt[M]; void Initialize() { memset(head,0,sizeof head); tot=1; } void Add(int x,int y,int z) { table[++tot].to=y; table[tot].f=z; table[tot].next=head[x]; head[x]=tot; } void Link(int x,int y,int z) { Add(x,y,z); Add(y,x,0); } bool BFS() { static int q[M]; int i,r=0,h=0; memset(dpt,-1,sizeof dpt); q[++r]=S;dpt[S]=1; while(r!=h) { int x=q[++h]; for(i=head[x];i;i=table[i].next) if(table[i].f&&!~dpt[table[i].to]) { dpt[table[i].to]=dpt[x]+1; q[++r]=table[i].to; if(table[i].to==T) return true; } } return false; } int Dinic(int x,int flow) { int i,left=flow; if(x==T) return flow; for(i=head[x];i&&left;i=table[i].next) if(table[i].f&&dpt[table[i].to]==dpt[x]+1) { int temp=Dinic(table[i].to,min(left,table[i].f)); left-=temp; table[i].f-=temp; table[i^1].f+=temp; } if(left) dpt[x]=-1; return flow-left; } } bool Judge(int x) { using namespace Union_Find_Set; using namespace Max_Flow; Union_Find_Set::Initialize(); Max_Flow::Initialize(); static int degree[M]; //入度+1 出度-1 int i; memset(degree,0,sizeof degree); for(i=1;i<=m;i++) { if(edges[i].z2<=x) { Union(edges[i].x,edges[i].y); degree[edges[i].x]++; degree[edges[i].y]--; Link(edges[i].x,edges[i].y,1); } else if(edges[i].z1<=x) { Union(edges[i].x,edges[i].y); degree[edges[i].x]--; degree[edges[i].y]++; } } if(cnt>=2) return false; for(i=1;i<=n;i++) { if(degree[i]&1) return false; if(degree[i]>0) Link(S,i,degree[i]>>1); else Link(i,T,-degree[i]>>1); } while( BFS() ) Dinic(S,INF); for(i=head[S];i;i=table[i].next) if(table[i].f) return false; return true; } } int Bisection(int l,int r) { using namespace Euler_Circuit; while(l+1<r) { int mid=l+r>>1; if( Judge(mid) ) r=mid; else l=mid; } return Judge(l)?l:r; } int main() { int i,x,y,z1,z2; cin>>n>>m; for(i=1;i<=m;i++) { scanf("%d%d%d%d",&x,&y,&z1,&z2); if(z1>z2) swap(x,y),swap(z1,z2); edges[i].x=x; edges[i].y=y; edges[i].z1=z1; edges[i].z2=z2; max_num=max(max_num,z1); max_num=max(max_num,z2); } int ans=Bisection(1,max_num+1); if(ans==max_num+1) cout<<"NIE"<<endl; else cout<<ans<<endl; return 0; }
BZOJ 2095 Poi2010 Bridges 二分答案+网络流
原文地址:http://blog.csdn.net/popoqqq/article/details/44015857