博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
「POI 2010」Bridges
阅读量:5107 次
发布时间:2019-06-13

本文共 2870 字,大约阅读时间需要 9 分钟。

题目链接

\(Solution\)

看到"最大值最小",就知道应该要二分

二分之后,对于每个\(mid\),只要计算小于\(mid\)的边,然后在剩下的图中判断有无欧拉回路

但这个图是一个混合图.

先对每条无向边随意的定向,统计每个点入度和出度的差,如果有一个点的入度和出度的奇偶性不同,那么就肯定无解(而改变无向边方向的话,会让它们的入读\(-\)出度变化\(2\),则他们的差无法变为\(0\),所以无法相同)

如果入度\(-\)出度\(=x\),若\(x < 0\),就向\(t\)连一条\(abs(x/2)\) 的边,否则就从源点连一条\(abs(x/2)\)的边,对于原来定向的无向边\((a,b)\),建立一条从\(b\)\(a\),容量为\(1\)(这个表示的意义时将\(a->b\)这一条边变成了从\(b->a\))

流一条流就代表将一条无向边反向

如果满流则存在欧拉回路

\(Code\)

#include
#define rg register#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);using namespace std;const int inf=1e9;int read(){ int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0'&&c<='9') x=x*10+c-48,c=getchar(); return f*x;}struct node{ int to,next,v;}a[200001];int head[20001],cnt=1,n,m,s,t,x,y,z,minx,maxx,dep[20001];void add(int x,int y,int c){ a[++cnt].to=y,a[cnt].next=head[x],a[cnt].v=c,head[x]=cnt; a[++cnt].to=x,a[cnt].next=head[y],a[cnt].v=0,head[y]=cnt;}queue
q;int bfs(){ memset(dep,0,sizeof(dep)); q.push(s); dep[s]=1; while(!q.empty()){ int now=q.front(); q.pop(); for(int i=head[now];i;i=a[i].next){ int v=a[i].to; if(!dep[v]&&a[i].v>0) dep[v]=dep[now]+1,q.push(v); } } if(dep[t]) return 1; return 0;}int dfs(int k,int list){ if(k==t||!list) return list; for(int i=head[k];i;i=a[i].next){ int v=a[i].to; if(dep[v]==dep[k]+1&&a[i].v>0){ int p=dfs(v,min(list,a[i].v)); if(p){ a[i].v-=p; a[i^1].v+=p; return p; } } } return dep[k]=0;}int Dinic(){ int ans=0,k; while(bfs()) while((k=dfs(s,inf))) ans+=k; return ans;}int A[20001],B[20001],C[20001],D[20001],vis[10001],tot;bool build(int x){ memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); s=0,t=n+1,cnt=1,tot=0; for(int i=1;i<=m;i++){ if(C[i]<=x) vis[A[i]]--,vis[B[i]]++; if(D[i]<=x) add(B[i],A[i],1); } for(int i=1;i<=n;i++) if(vis[i]&1) return 0; for(int i=1;i<=n;i++){ if(vis[i]>0) tot+=vis[i]/2,add(s,i,vis[i]/2); else add(i,t,-vis[i]/2); } return 1;}bool check(int x){ bool res=build(x); if(!res) return 0; return Dinic()==tot;}int main(){ n=read(),m=read(),minx=2147483647,maxx=0; for(int i=1;i<=m;i++){ A[i]=read(),B[i]=read(),C[i]=read(),D[i]=read(); if(C[i]>D[i]) swap(A[i],B[i]),swap(C[i],D[i]); minx=min(C[i],minx),maxx=max(maxx,D[i]); } int l=minx,r=maxx,ans=0; while(l<=r){ int mid=(l+r)>>1; if(check(mid)) r=mid-1,ans=mid; else l=mid+1; } if(!ans) puts("NIE"),exit(0); printf("%d",ans); return 0;}

转载于:https://www.cnblogs.com/hbxblog/p/11098058.html

你可能感兴趣的文章
[多项式算法](Part 2)NTT 快速数论变换 学习笔记
查看>>
[多项式算法](Part 4)FWT 快速沃尔什变换 学习笔记
查看>>
[多项式算法](Part 3)MTT 任意模数FFT/NTT 学习笔记
查看>>
[多项式算法](Part 1)FFT 快速傅里叶变换 学习笔记
查看>>
[多项式算法](Part 5)分治FFT 学习笔记
查看>>
[多项式算法]多项式求逆 学习笔记
查看>>
[总结]2019年9月 OI学习/刷题记录
查看>>
[LOJ2980]「THUSCH 2017」大魔法师
查看>>
[LOJ 6199/Luogu P4688][Ynoi2016]掉进兔子洞
查看>>
[Luogu P5068][Ynoi2015]我回来了
查看>>
[总结]2019年10月 OI学习/刷题记录
查看>>
[BZOJ4870/LOJ2143][Shoi2017]组合数问题
查看>>
切词框架jcseg,入门
查看>>
深入理解Spring Redis的使用 (一)、Spring Redis基本使用
查看>>
windows如何安装mysql
查看>>
Class.getResourceAsStream()与ClassLoader.getResourceAsStream()获取资源时的路径说明
查看>>
玩转深拷贝/浅拷贝
查看>>
java之反射
查看>>
博客阅读笔记
查看>>
[恢]hdu 1050
查看>>