最大值最小,是二分

转化为判定问题:给定一个混合图,问是否存在欧拉回路

首先,有向图存在欧拉回路的充要条件是每个点的入度等于出度,现在我们有一个混合图,我们要做的就是给其中的无向边定向,使得它变成有向图之后存在欧拉回路

记点$x$的入度为$in_x$,出度为$out_x$,我们的目标是使得每个点$x$满足$in_x-out_x=0$

先随便给每条无向边定向,这样不一定满足要求,所以我们必须让某些边反向,反向$a\rightarrow b$会让$in_a-out_a$增加$2$,让$in_b-out_b$减少$2$,所以如果存在$in_x-out_x\equiv1(\text{mod }2)$那么无解

为了决定是否反向某些无向边,我们这样建图:

对于$in_x\lt out_x$的$x$,连边$x\rightarrow T$,容量为$\dfrac{out_x-in_x}2$

对于$in_x\gt out_x$的$x$,连边$S\rightarrow x$,容量为$\dfrac{in_x-out_x}2$

对于一条无向边,如果一开始硬点它的方向为$x\rightarrow y$,那么连边$y\rightarrow x$,权值为$1$

这样建图跑最大流,每流过一条原图中的无向边就相当于将它反向(这条无向边的两个端点的流量之和就是$\left|in_x-out_x\right|$的改变量),跑最大流是因为我们想要尽可能地缩小$in_x$和$out_x$的差距,如果满流,自然就存在欧拉回路了

#include<stdio.h>
#include<string.h>
const int inf=2147483647;
int abs(int x){return x>0?x:-x;}
int min(int a,int b){return a<b?a:b;}
int h[1010],cur[1010],nex[10010],to[10010],cap[10010],dis[1010],q[10010],M,S,T;
void add(int a,int b,int c){
	M++;
	to[M]=b;
	cap[M]=c;
	nex[M]=h[a];
	h[a]=M;
	M++;
	to[M]=a;
	cap[M]=0;
	nex[M]=h[b];
	h[b]=M;
}
bool bfs(){
	int head,tail,x,i;
	memset(dis,-1,sizeof(dis));
	head=tail=1;
	q[1]=S;
	dis[S]=0;
	while(head<=tail){
		x=q[head];
		head++;
		for(i=h[x];i;i=nex[i]){
			if(cap[i]&&dis[to[i]]==-1){
				dis[to[i]]=dis[x]+1;
				if(to[i]==T)return 1;
				tail++;
				q[tail]=to[i];
			}
		}
	}
	return 0;
}
int dfs(int x,int flow){
	if(x==T)return flow;
	int i,f;
	for(i=cur[x];i;i=nex[i]){
		if(cap[i]&&dis[to[i]]==dis[x]+1){
			f=dfs(to[i],min(flow,cap[i]));
			if(f){
				cap[i]-=f;
				cap[i^1]+=f;
				if(cap[i])cur[x]=i;
				return f;
			}
		}
	}
	dis[x]=-1;
	return 0;
}
int dicnic(){
	int ans=0,tmp;
	while(bfs()){
		memcpy(cur,h,sizeof(h));
		while(tmp=dfs(S,inf))ans+=tmp;
	}
	return ans;
}
int n,m,in[1010],ou[1010];
struct edge{
	int x,y,a,b;
}e[2010];
bool check(int lim){
	int i,s;
	memset(h,0,sizeof(h));
	memset(in,0,sizeof(in));
	memset(ou,0,sizeof(ou));
	M=1;
	for(i=1;i<=m;i++){
		if(e[i].a<=lim&&e[i].b<=lim){
			add(e[i].y,e[i].x,1);
			ou[e[i].x]++;
			in[e[i].y]++;
		}else if(e[i].a<=lim){
			ou[e[i].x]++;
			in[e[i].y]++;
		}else if(e[i].b<=lim){
			ou[e[i].y]++;
			in[e[i].x]++;
		}else
			return 0;
	}
	s=0;
	for(i=1;i<=n;i++){
		if(abs(in[i]-ou[i])&1)return 0;
		if(in[i]<ou[i])add(i,T,(ou[i]-in[i])>>1);
		if(in[i]>ou[i]){
			add(S,i,(in[i]-ou[i])>>1);
			s+=(in[i]-ou[i])>>1;
		}
	}
	return s==dicnic();
}
int main(){
	int i,l,r,mid,ans;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].a,&e[i].b);
	S=n+1;
	T=n+2;
	ans=-1;
	l=0;
	r=1000;
	while(l<=r){
		mid=(l+r)>>1;
		if(check(mid)){
			ans=mid;
			r=mid-1;
		}else
			l=mid+1;
	}
	if(ans==-1)
		puts("NIE");
	else
		printf("%d",ans);
}

[BZOJ2095]Bridges的更多相关文章

  1. 【BZOJ2095】[Poi2010]Bridges 动态加边网络流

    [BZOJ2095][Poi2010]Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个 ...

  2. BZOJ2095 POI2010 Bridges 【二分+混合图欧拉回路】

    BZOJ2095 POI2010 Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛 ...

  3. 【BZOJ2095】[Poi2010]Bridges

    [BZOJ2095][Poi2010]Bridges 题面 darkbzoj 题解 首先可以想到二分答案,那么我们就是要求我们新图中给所有边定向是否存在欧拉回路. 而有向图存在欧拉回路的充要条件为所有 ...

  4. [BZOJ2095][Poi2010]Bridges 最大流(混合图欧拉回路)

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海, ...

  5. [BZOJ2095][Poi2010]Bridges 二分+网络流

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1187  Solved: 408[Submit][Sta ...

  6. BZOJ2095 [Poi2010]Bridges

    首先二分答案...然后这张图变成了有一些有向边,有一些无向边 然后就是混合图欧拉回路的判断 我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度 对于混合图...先不管有向边,把无向边 ...

  7. BZOJ2095:[POI2010]Bridges(最大流,欧拉图)

    Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1 ...

  8. bzoj千题计划228:bzoj2095: [Poi2010]Bridges

    http://www.lydsy.com/JudgeOnline/problem.php?id=2095 二分答案,判断是否存在混合图的欧拉回路 如果只有一个方向的风力<=mid,这条边就是单向 ...

  9. bzoj2095: [Poi2010]Bridges(二分+混合图求欧拉回路)

    传送门 这篇题解讲的真吼->这里 首先我们可以二分一个答案,然后把所有权值小于这个答案的都加入图中 那么问题就转化为一张混合图(既有有向边又有无向边)中是否存在欧拉回路 首先 无向图存在欧拉回路 ...

随机推荐

  1. Java8 时间处理

    Table of Contents 前言 时间单位和时区 时间点 时间段 时间的解析和格式化 时区时间 兼容旧接口 结语 前言 时间处理是一个经常会用到但又不那么好用的功能,其中的主要问题在于对人友好 ...

  2. echarts 柱状图下钻功能

    var drillDown = {   getOption : function () {   var option = null;   option = {   title: {   text: ' ...

  3. PCA学习笔记

    主成分分析(Principal Component Analysis,简称PCA)是最常用过的一种降维方法 在引入PCA之前先提到了如何使用一个超平面对所有的样本进行恰当的表达? 即若存在这样的超平面 ...

  4. Android开发实例总结

    写一个修改密码的界面 1画界面总结: 需要弄清楚什么地方用相对布局,什么地方使用线性布局 希望这过后自己花时间去弄清楚他们内嵌的的所有组件以及组件的属性包括用法. 2逻辑总结: 逻辑描述总是那么几步的 ...

  5. React跨域问题解决

    https://segmentfault.com/q/1010000012732581 非跨域问题报错 -rpccorsdomain="http://localhost:3000" ...

  6. 替换localhost:8080(假域名,本地使用)

    1. 更改servers 的端口号为 80 (默认 8080),此时就不用再输入 8080了. 2. 找到 C:\Windows\System32\drivers\etc 下的 hosts 文件,用记 ...

  7. BZOJ1004 [HNOI2008]Cards 【burnside定理 + 01背包】

    题目链接 BZOJ1004 题解 burnside定理 在\(m\)个置换下本质不同的染色方案数,等于每种置换下不变的方案数的平均数 记\(L\)为本质不同的染色方案数,\(m\)为置换数,\(f(i ...

  8. 常用shell脚本命令

    常用shell脚本命令 1.显示包含文字aaa的下一行的内容: sed -n '/aaa/{n;p;}' filename 2.删除当前行与下一行的内容: sed -i '/aaa/{N;d;}' f ...

  9. java自定义类型 比较排序 Comparator接口

    String service_time = "6:00:00,7:00:00,8:00:00,9:00:00,10:00:00,11:00:00,12:00:00,13:00:00,14:0 ...

  10. html中<a href> </a>的用法

    一.绝对跳转    <a href="http://www.baidu.com/">百度</a> 二.相对跳转有如下方式,需要了解(以下的例子中,分别以你的 ...