https://darkbzoj.cf/problem/2095

bzoj 相同的题挂了,这个oj可以写。

题目就是要我们找一条欧拉回路(每个桥经过一次就好,不管方向),使得这条回路上权值最大的尽量小
二分答案是显然的,关键是如何check

每次二分一个mid,大于mid的边都不选,那么就有一些方向不能走了,原图就是一个混合图,问题就转化成了一个混合图判定欧拉回路问题(如果有一条边两个方向都不能走,那肯定不存在欧拉回路)
对于那些单向边,直接统计度数就可以。对于两个方向都可以走的边,先随便定一个方向,假设是u->v,统计度数,并且在网络图里加一条边u->v,流量为1。
最后遍历所有的点u,如果入度与出度之差为奇数,显然无解(某一次进去就出不来了,或者出来就进不去了)
如果u出度大于入度,那么加边S->u,流量(out-in)/2   就是要调整多少条边 
如果u入度大于出度,那么加边u->T,流量(in-out)/2
最后满流才有欧拉回路

这样做的正确性:
双向边是随意定向的,因此这个定向可能是错的,才会导致一些点出度和入度不相等(如果欧拉回路本来存在的话)。如果把一条原本是v->u的边定成了u->v,那么u就多了出度,v就少了入度。要修正这个错误,就需要让u->v边反向,达到u出度-1,v入度+1的目的。也就是S->u->v->T这条流量的含义。当然反过来建也是可以的:S->v->u->T
如果最后不能满流,说明有一些点的入度没办法等于出度,那肯定不存在欧拉回路

AC代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=4e3+,mod=1e9+,inf=0x3f3f3f3f;
typedef long long ll;
struct edge
{
int from,to,c,f;
edge(int u,int v,int c,int f):from(u),to(v),c(c),f(f) {}
};
int n,m;
vector<edge> edges;
vector<int> g[maxn];
int d[maxn];//从起点到i的距离
int cur[maxn];//当前弧下标
struct bian
{
int a,b,c,d;
}qiao[maxn];
int in[maxn],out[maxn];
void init()
{
for(int i=; i<=n+; i++) g[i].clear(); //要把源点汇点算进去!!
edges.clear();
}
void addedge(int from,int to,int c) //加边 支持重边
{
edges.push_back(edge(from,to,c,));
edges.push_back(edge(to,from,,));
int siz=edges.size();
g[from].push_back(siz-);
g[to].push_back(siz-);
}
int bfs(int s,int t) //构造一次层次图
{
memset(d,-,sizeof(d));
queue<int> q;
q.push(s);
d[s]=;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=;i<g[x].size();i++)
{
edge &e=edges[g[x][i]];
if(d[e.to]<&&e.f<e.c) //d[e.to]=-1表示没访问过
{
d[e.to]=d[x]+;
q.push(e.to);
}
}
}
return d[t];
}
int dfs(int x,int a,int t) // a表示x点能接收的量
{
if(x==t||a==)return a;
int flow=,f;//flow总的增量 f一条增广路的增量
for(int &i=cur[x];i<g[x].size();i++)//cur[i] &引用修改其值 从上次考虑的弧
{
edge &e=edges[g[x][i]];
if(d[x]+==d[e.to]&&(f=dfs(e.to,min(a,e.c-e.f),t))>) //按照层次图增广 满足容量限制
{
e.f+=f;
edges[g[x][i]^].f-=f; //修改流量
flow+=f;
a-=f;
if(a==) break;
}
}
return flow;
}
int maxflow(int s,int t)
{
int flow=;
while(bfs(s,t)!=-) //等于-1代表构造层次图失败 结束
{
memset(cur,,sizeof(cur));
flow+=dfs(s,inf,t);
}
return flow;
}
int check(int mid)
{
memset(in,,sizeof(in));
memset(out,,sizeof(out));
init();
for(int i=;i<m;i++)
{
if(qiao[i].c<=mid&&qiao[i].d<=mid)
{
addedge(qiao[i].a,qiao[i].b,);
in[qiao[i].b]++,out[qiao[i].a]++;
}
else if(qiao[i].c<=mid)
in[qiao[i].b]++,out[qiao[i].a]++;
else if(qiao[i].d<=mid)
in[qiao[i].a]++,out[qiao[i].b]++;
else
return ;
}
int sum=;
for(int i=;i<=n;i++)
{
int temp=out[i]-in[i];
if(temp&)
return ;
if(temp>)
addedge(n+,i,temp/),sum+=temp/;
if(temp<)
addedge(i,n+,-temp/);
}
return sum==maxflow(n+,n+);
}
int main()
{
scanf("%d%d",&n,&m);
int u,v,c,f;
for(int i=;i<m;i++)
{
scanf("%d%d%d%d",&u,&v,&c,&f);
qiao[i]={u,v,c,f};
}
int l=,r=,ans=-;
while(l<=r)
{
int mid=(l+r)/;
if(check(mid))
{
ans=mid;
r=mid-;
}
else
l=mid+;
}
if(ans==-)
printf("NIE\n");
else
printf("%d\n",ans);
}

[Poi2010]Bridges 最大流+二分答案 判定混合图欧拉回路的更多相关文章

  1. POJ1637 Sightseeing tour(判定混合图欧拉回路)

    有向连通图存在欧拉回路的充要条件是所有点入度=出度. 首先随便给定所有无向边一个方向(不妨直接是u->v方向),记录所有点的度(记:度=入度-出度). 这时如果有点的度不等于0,那么就不存在欧拉 ...

  2. bzoj 2095: [Poi2010]Bridges [混合图欧拉回路]

    2095: [Poi2010]Bridges 二分答案,混合图欧拉路判定 一开始想了一个上下界网络流模型,然后发现不用上下界网络流也可以 对于无向边,强制从\(u \rightarrow v\),计算 ...

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

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

  4. 【BZOJ-2095】Bridge 最大流 + 混合图欧拉回路 + 二分

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 604  Solved: 218[Submit][Stat ...

  5. POJ 1637 - Sightseeing tour - [最大流解决混合图欧拉回路]

    嗯,这是我上一篇文章说的那本宝典的第二题,我只想说,真TM是本宝典……做的我又痛苦又激动……(我感觉ACM的日常尽在这张表情中了) 题目链接:http://poj.org/problem?id=163 ...

  6. POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)

    http://poj.org/problem?id=1637 题意:给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路. 思路: 构成有向图欧拉回路的要求是入度=出度,无向图 ...

  7. POJ 1637 Sightseeing tour ★混合图欧拉回路

    [题目大意]混合图欧拉回路(1 <= N <= 200, 1 <= M <= 1000) [建模方法] 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为 ...

  8. POJ 1637 混合图欧拉回路

    先来复习一下混合图欧拉回路:给定一张含有单向边和双向边的图,使得每一点的入度出度相同. 首先对于有向边来说,它能贡献的入度出度是确定的,我们不予考虑.对于无向图,它可以通过改变方向来改变两端点的出入度 ...

  9. poj1637Sightseeing tour(混合图欧拉回路)

    题目请戳这里 题目大意:求混合图欧拉回路. 题目分析:最大流.竟然用网络流求混合图的欧拉回路,涨姿势了啊啊.. 其实仔细一想也是那么回事.欧拉回路是遍历所有边一次又回到起点的回路.双向图只要每个点度数 ...

随机推荐

  1. 多线程threadvar 变量设定

    Delphi管理多线程之线程局部存储:threadvar 尽管多线程能够解决许多问题,但是同时它又给我们带来了很多的问题.其中主要的问题就是:对全局变量或句柄这样的全局资源如何访问?另外,当必须确保一 ...

  2. springboot文字转语音(jacob)

    近期项目中出现在离线情况下文字转语音的需求 进过尝试返现jacob还不错 一下为开发记录: 1.pom.xml中引入jacob.jar <dependency> <groupId&g ...

  3. bootstrap历练实例:标签式的导航菜单

    本章将讲解bootstrap提供的用于定义导航元素的一些选项,它使用相同的标签和基类.nav.Bootsrtap也提供了一个用于共享标记和状态的帮助器类.改变修饰的class,可以在不同的样式间进行切 ...

  4. ios retain copy 以及copy协议

    阅读本文之前首先了解Copy与Retain的区别: Copy是创建一个新对象,Retain是创建一个指针,引用对象计数加1. Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的 ...

  5. ios之自定义导航栏上的返回按钮

    导航栏的按钮,右边的按钮是可以自己随意添加的.但左边的返回按钮怎么定制?你会说,添加一个自己的按钮呗!你可以试试看,这样行不行. 正确的答案是重载UINavigationController类的pus ...

  6. awk纯干货

    AWK的惊人表现: Awk设计的目的:简化一般文本处理的工作. 属于POSIX的一部分. AWK命令行: Awk的调用可以定义变量.提供程序并且指定输入文件: Awk [ -F fs ]  [ -v ...

  7. cookies,sessionStorage和localStorage的相同点和不同点?

    相同点:都存储在客户端. 不同点: 1.存储大小: cookies数据大小不能超过4k sessionStorage和localStorage虽然也有存储大小的限制,但比cookies大得多,可以达到 ...

  8. (6)zabbix主机与组配置

    1. 创建主机方法 1.1 新建主机configuration(配置)->Hosts(主机)->Create host(创建主机) 见前面的博文 1.2 克隆/完全克隆主机 2. 主机参数 ...

  9. Cocos2d-x学习资料集锦

    Cocos2d-x学习资料集锦: 1.Cocos2d-x官方中文文档:https://github.com/chukong/cocos-docs/blob/master/catalog/zh.md 推 ...

  10. Knockout v3.4.0 中文版教程-14-控制文本内容和外观-style绑定

    5. style绑定 目的 style绑定用来给关联的DOM元素添加或移除一个或多个样式值.在如下情况很有用,比如,当某些值为负时,高亮显示,或者设置容器元素的宽度来匹配数值的改变. (注意:如果你不 ...