【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 ...
随机推荐
- [转]Apache Doris资料汇总
参考资料 https://www.toutiao.com/i6709706901770207748/?tt_from=weixin&utm_campaign=client_share& ...
- 安装keepalived OpenSSL is not properly installed on your system. !!!
错误信息: configure: error: !!! OpenSSL is not properly installed on your system. !!! !!! Can not includ ...
- Web前端——Html常用标签及属性
html 常用的标题等标签就不记录了,只记录一下比较少见的标签以及属性 表格 table td 单元格 tr 表的行 th 表头 td或th可以下面的两个属性达到跨行或跨列 表格跨行 rowspan ...
- C# download big file
I had validated this.To download SSMS which is more than 500M+ static void Main(string[] args) { str ...
- wpf dual monitor
<Window x:Class="DualMonitors.Views.WinLeft" xmlns="http://schemas.microsoft.com/w ...
- Python--方法/技巧在哪用的典型例子
就我个人在学习Python的过程中,经常会出现学习了新方法后,如果隔上几天不用,就忘了的情况,或者刚学习的更好的方法没有得到应用,还是沿用已有的方法,这样很不利于学习和掌握新姿势,从而拉长学习时间,增 ...
- u盘 安装 centOS 7
实际上, 对于服务器的安装, 最好是能够远程批量安装(可能有些难度, 不是专业运维) 镜像下载地址: http://59.80.44.49/isoredirect.centos.org/centos/ ...
- RSA 非对称加密算法的Java实现
关于RSA的介绍Google一下很多,这里不做说明.项目开发中一般会把公钥放在本地进行加密,服务端通过私钥进行解密.Android项目开发中要用到这个加密算法,总结后实现如下: import andr ...
- [b0002] Hadoop HDFS cmd常用命令练手
目的: 学会HDFS CLI 常用操作 环境: Hadoop 2.6.4 伪分布式版 环境搭建参考本博客前篇文章: 伪分布式 hadoop 2.6.4 帮助: hadoop@ssmaster:~$ h ...
- 游戏设计模式——C++单例类
前言: 本文将探讨单例类设计模式,单例类的懒汉模式/饿汉模式,单例类的多线程安全性,最后将利用C++模板减少单例类代码量. 本文假设有一个Manager管理类,并以此为探究单例类的设计模式. 懒汉模式 ...