【UOJ#389】【UNR#3】白鸽(欧拉回路,费用流)
【UOJ#389】【UNR#3】白鸽(欧拉回路,费用流)
题面
题解
首先第一问就是判断是否存在一条合法的欧拉回路,这个拿度数和连通性判断一下就行了。
第二问判断转的圈数,显然我们只需要考虑顺时针过一条从源点出发的射线的次数减去逆时针过的次数就好了。
于是我们就要在欧拉回路合法的基础上算第二问。
首先如果欧拉回路合法,那么每个点的入度要等于出度,这个东西有点类似上下界网络流,即强制了每个点的度数的上下界。我们可以类似上下界网络流,先给每条边强行定向,对于入度出度差不为令的点,分别和源点和汇点连边,以追求平衡。
那么我们定向之后,边有边权,那么连一条反边,容量为\(1\),费用为边权的二倍,表示如果这条边反向则要减少的权值。
于是答案就是定向的边权和减去最小费用最大流。
注意一下常数问题。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define MAX 20200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,m,ans,dg[MAX];
struct Node{int x,y;}p[MAX];
struct Line{int v,next,w,fy;}e[MAX<<2];
int h[MAX],cnt=2,cur[MAX];
inline void Add(int u,int v,int w,int fy)
{
e[cnt]=(Line){v,h[u],w,fy};h[u]=cnt++;
e[cnt]=(Line){u,h[v],0,-fy};h[v]=cnt++;
}
deque<int> Q;
int S,T,dis[MAX];
bool vis[MAX];
bool SPFA()
{
for(int i=S;i<=T;++i)dis[i]=1e9,vis[i]=false;
Q.push_back(S);dis[S]=0;vis[S]=true;
while(!Q.empty())
{
int u=Q.front();Q.pop_front();
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(!e[i].w)continue;
if(dis[v]>dis[u]+e[i].fy)
{
dis[v]=dis[u]+e[i].fy;
if(!vis[v])
{
vis[v]=true;
if(e[i].w>0)Q.push_back(v);
else Q.push_front(v);
}
}
}
vis[u]=false;
}
return dis[T]<1e9;
}
int dfs(int u,int flow)
{
if(u==T||!flow)return flow;
int ret=0;vis[u]=true;
for(int &i=cur[u];i;i=e[i].next)
{
int v=e[i].v;if(!e[i].w)continue;
if(!vis[v]&&dis[v]==dis[u]+e[i].fy)
{
int d=dfs(v,min(flow,e[i].w));
ret+=d;flow-=d;
e[i].w-=d;e[i^1].w+=d;
if(!flow){vis[u]=false;return ret;}
}
}
vis[u]=false;dis[u]=1e9;
return ret;
}
int MCMF()
{
int ret=0;
while(SPFA())
{
for(int i=S;i<=T;++i)cur[i]=h[i];
ret+=dfs(S,1e9)*dis[T];
}
return ret;
}
int f[MAX];
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
int main()
{
n=read();m=read();S=0;T=n+1;
for(int i=1;i<=n;++i)p[i].x=read(),p[i].y=read();
for(int i=1;i<=n;++i)f[i]=i;
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
if(1ll*p[u].x*p[v].y>1ll*p[u].y*p[v].x)swap(u,v);
int val=p[u].y>0&&p[v].y<=0;++dg[u];--dg[v];
Add(u,v,1,2*val);ans+=val;
f[getf(u)]=getf(v);vis[u]=vis[v]=true;
}
for(int i=1;i<=n;++i)if(vis[i]&&getf(i)!=getf(1)){puts("-1");return 0;}
for(int i=1;i<=n;++i)if(dg[i]&1){puts("-1");return 0;}
for(int i=1;i<=n;++i)
if(dg[i]>0)Add(S,i,dg[i]>>1,0);
else if(dg[i]<0)Add(i,T,-dg[i]>>1,0);
printf("%d\n",ans-MCMF());
return 0;
}
【UOJ#389】【UNR#3】白鸽(欧拉回路,费用流)的更多相关文章
- UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
题目链接 http://uoj.ac/contest/47/problem/455 题解 模拟费用流,一个非常神奇的东西. 本题即为WC2019 laofu的讲课中的Problem 8,经典的老鼠进洞 ...
- hdu4067 费用流(混合欧拉的宽展和延伸)
题意: 给以一个图,每个有向边都有两个权值,a,b其中a是保留这条边的花费,b是删除这条边的花费,让你删去一些边使图满足一下要求: (1)只有一个起点和一个终点 (2)所有的边都是又向的 ...
- hdu-5988 Coding Contest(费用流)
题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot ...
- POJ2195 Going Home[费用流|二分图最大权匹配]
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22088 Accepted: 11155 Desc ...
- BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]
3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 960 Solved: 5 ...
- 洛谷 1004 dp或最大费用流
思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...
- Codeforces 730I [费用流]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...
- zkw费用流+当前弧优化
zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...
- 【BZOJ-4213】贪吃蛇 有上下界的费用流
4213: 贪吃蛇 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 58 Solved: 24[Submit][Status][Discuss] Desc ...
随机推荐
- MySQL for OPS 12:锁处理
写在前面的话 在前面的内容中提到过,在以前的 MyISAM 中锁是表级锁,InnoDB 是行级锁.这个锁到底是啥样,怎么找出来,这一节就主要做这个. 定位锁的问题 上一节我们创建了一个 1000万数据 ...
- springcloud微服务多节点高性能、高可用、高并发部署
1. 共有三个服务 discovery服务,domain服务,gateway服务. discovery服务是用来注册其他服务的,作为服务治理用. domain服务是主业务服务. gateway服务是所 ...
- HikariCP监控指标介绍和应用
概述 HikariCP提供了一些监控指标,他的监控指标都是基于MicroMeter提供出来的,然后支持Prometheus和Dropwizard.本次我们将讨论一下HikariCp的监控指标有哪些,为 ...
- SILK编码语音转WAV格式
- SILK编码 SILK采样率可为8.12.16或24 kHz,比特率可为6至40 kbit/s.对应到报文层面的直观印象,即SILK编码的语音数据每帧长度是不等的. SILK编码已经开源,目前可下 ...
- 滴滴出行开源项目doraemonkit食用指南
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/94 doraemonkit 功能介绍 一两周前在地铁上刷任 ...
- MongoDB安装调试
1:安装 去mongodb的官网http://www.mongodb.org/downloads下载32bit的包 解压后会出现以下文件 在安装的盘C:下建立mongodb文件夹,拷贝bin文件夹到该 ...
- Python数值类型和序列类型
int.float.bool这三个数值类型和常用序列类型的定义和使用 数值类型的基本计算 序列类型的索引取值.切片.成员运算等序列类型的通用操作 complex(复数).decimal(定点数).ma ...
- [PHP] 新版本PHP7.4与新版本MySQL8认证问题
mysql8的默认密码加密方式是caching_sha2_password,PHP7.4连接mysql的加密方式也为caching_sha2_password,这个地方要注意. 当为了兼容旧版的客户端 ...
- php实现图片下载
download.php下载代码 <?php //获取要下载的文件名 $filename = $_GET['filename']; //设置头信息 header('Content-Disposi ...
- 使用flask搭建微信公众号:完成token的验证
上一篇文章讨论了官方给的例子验证token失败的解决方法:微信公众号token验证失败 想了一下,还是决定不适用web.py这个框架.因为搜了一下他的中文文档不多,学起来可能会有点麻烦.而且看着他没有 ...