[WC2007]剪刀石头布(最大流)
一句话题意:给定一张图,每两点之间有一条有向边或无向边,把所有无向边定向,使图中三元环个数尽量多
因为原图是一个完全图,假设图中任意三点都能构成三元环,那么途中三元环的个数为:\(\binom{n}{3}\)。
那么如果一个三元组不是三元环,那么有一个点的出度为2。
我们假设一个点的出度为d,那么对于这个点,三元环会减少\(\frac{d (d-1)}{2}\)
所以三元环的数量为:\(\binom{n}{3}- \sum_{i=1}^n\binom{d[i]}{2}=\binom{n}{3}- \sum_{i=1}^n\frac{d[i] (d[i]-1)}{2}\)
所以我们要最小化:$ \sum_{i=1}^n\frac{d[i] (d[i]-1)}{2}$的值。
怎么做呢?
如果我们对于一条无向边,可能让u出度+1,也可能让v出度+1,非黑即白,所以我们可以考虑费用流。
观察柿子\(\frac{d[i] (d[i]-1)}{2}\),容(hen)易(nan)想到小学等差数列求和公式,于是我们可以将一个点的贡献看成\((0+1+2+3+……+d[i]-1)\)
把每一条边看成一个点,从源点向每条边连一条容量为1,费用为0的边。
对于一条无向边,往u,v分别建一条容量为1,费用为0的边。
有向边则把边和v建一条容量为1,费用为0的边。
每个点向汇点连n条容量为1,费用为0-(n-1)递增的边,表示上面的等差数列(可以表示出任何出度的情况)
最后就是费用流的板子了
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define inf 123456789
#define debug printf("Now is Line : %d\n",__LINE__)
il int read()
{
re int x=0,f=1; re char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return x*f;
}
#define maxn 105
#define maxm 105*105
struct edge
{
int v,w,val,next;
}e[maxm<<3];
int n,a[maxn][maxn],S,T,maxflow,cost,vis[maxm],dis[maxm],head[maxm],cnt=1,pa;
il void add(int u,int v,int val,int w)
{
e[++cnt]=(edge){v,w,val,head[u]};
head[u]=cnt;
e[++cnt]=(edge){u,-w,0,head[v]};
head[v]=cnt;
}
queue<int>q;
il bool spfa()
{
memset(vis,0,sizeof(vis));
memset(dis,127,sizeof(dis));
dis[S]=0; q.push(S);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(re int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w&&e[i].val>0)
{
dis[v]=dis[u]+e[i].w;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
return dis[T]!=2139062143;
}
il int dfs(int u,int mi)
{
if(u==T)
{
vis[T]=1;
return mi;
}
vis[u]=1;
int use=0;
for(re int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if((!vis[v]||v==T)&&e[i].val>0&&dis[v]==dis[u]+e[i].w)
{
int low=dfs(v,min(mi-use,e[i].val));
if(low>0)
{
cost+=low*e[i].w;
e[i].val-=low; e[i^1].val+=low;
use+=low;
}
}
}
return use;
}
il void dinic()
{
while(spfa())
{
vis[T]=1;
while(vis[T])
{
memset(vis,0,sizeof(vis));
dfs(S,inf);
}
}
int ans=((n-1)*(n-2)*n)/6;
ans-=cost;
printf("%d\n",ans);
}
int main()
{
n=read(); T=n*n+n+1;
for(re int i=1;i<=n;++i)
{
for(re int j=1;j<=n;++j)
{
a[i][j]=read();
if(i>=j) continue;
if(a[i][j]==2)
{
add(S,(i-1)*n+j,1,0);
add((i-1)*n+j,n*n+i,1,0);
add((i-1)*n+j,n*n+j,1,0);
}
else if(a[i][j]==1) add(S,n*n+j,1,0);
else add(S,n*n+i,1,0);
}
}
for(re int i=1;i<=n;++i)
{
for(re int j=0;j<n;++j) add(n*n+i,T,1,j);
}
dinic();
for(re int i=1;i<=n;++i)
{
for(re int j=i+1;j<=n;++j)
{
if(a[i][j]<2) continue;
for(re int k=head[(i-1)*n+j];k;k=e[k].next)
{
if(e[k].v&&e[k].val==0)
{
a[i][j]=(e[k].v-n*n==j);
a[j][i]=a[i][j]^1;
}
}
}
}
for(re int i=1;i<=n;++i,puts(""))
{
for(re int j=1;j<=n;++j) printf("%d ",a[i][j]);
}
return 0;
}
[WC2007]剪刀石头布(最大流)的更多相关文章
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...
- bzoj 2597 [Wc2007]剪刀石头布——费用流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 三个人之间的关系,除了“剪刀石头布”,就是有一个人赢了2局:所以考虑算补集,则每个人对 ...
- [WC2007]剪刀石头布——费用流
比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...
- BZOJ 2597: [Wc2007]剪刀石头布(费用流)
传送门 解题思路 考虑全集-不能构成三元环的个数.如果三个点不能构成三元环,一定有一个点的入度为\(2\),继续扩展,如果一个点的度数为\(3\),则会失去3个三元环.对于一个点来说,它所产生的不能构 ...
- [bzoj2597][Wc2007]剪刀石头布_费用流
[Wc2007]剪刀石头布 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 题解: 发现直接求三元环不好求,我们考虑任选三个点不是 ...
- 2597: [Wc2007]剪刀石头布
2597: [Wc2007]剪刀石头布 链接 分析: 费用流. 首先转化一下问题,整张图最优的情况是存在$C_n^3$个,即任意3个都行,然后考虑去掉最少不满足的三元环. 如果u赢了v,u向v连一条边 ...
- [Wc2007]剪刀石头布
[Wc2007]剪刀石头布 http://www.lydsy.com/JudgeOnline/problem.php?id=2597 Time Limit: 20 Sec Memory Limit: ...
- 【BZOJ2597】[Wc2007]剪刀石头布 最小费用流
[BZOJ2597][Wc2007]剪刀石头布 Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之 ...
- [Wc2007]剪刀石头布[补集转化+拆边]
2597: [Wc2007]剪刀石头布 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1157 Solved: ...
- BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)
题目大概是说n个人两两进行比赛,问如何安排几场比赛的输赢使得A胜B,B胜C,C胜A这种剪刀石头布的三元组最多. 这题好神. 首先,三元组总共有$C_n^3$个 然后考虑最小化不满足剪刀石头布条件的三元 ...
随机推荐
- js 条件判断
练习 小明身高1.75,体重80.5kg.请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数: 低于18.5:过轻 18.5-25:正常 25-28:过重 28-32:肥 ...
- Linux(DeepInOS) 下 mysql 的安装与基本配置
索引: 目录索引 参看代码 GitHub: DeepIn(GNU/Linux) MySQL 一.安装 sudo apt-get install mysql-server 期间需要输入两次密码,root ...
- Ubuntu上更改MySQL数据库数据存储目录
之前写过一篇博客"MySQL更改数据库数据存储目录",当时的测试环境是RHEL和CentOS,谁想最近在Ubuntu下面更改MySQL数据库数据存储目录时遇到了之前未遇到的问题,之 ...
- c/c++ linux 进程间通信系列2,使用UNIX_SOCKET
linux 进程间通信系列2,使用UNIX_SOCKET 1,使用stream,实现进程间通信 2,使用DGRAM,实现进程间通信 关键点:使用一个临时的文件,进行信息的互传. s_un.sun_fa ...
- jenkins+gitlab配置
jenkins配置 插件配置 Jenkins要实现持续集成自动部署需要安装 gitlab maven Publish Over SSH Git等几个插件 查看已经安装的插件 jenkins上集成 ...
- Elixir 简介
概述 Elixir 是一种基于 Erlang 虚拟机的函数式,面向并行的通用语言, 它是一门通用语言,所以不仅可以用在擅长的高可用,高并发场景下,也可以用在 web 开发等场景下. Erlang 诞生 ...
- 2017 百度杯丶二月场第一周WP
1.祸起北荒 题目: 亿万年前 天子之子华夜,被父神之神末渊上神告知六荒十海之北荒西二旗即将发生一场"百度杯"的诸神之战 他作为天族的太子必须参与到此次诸神之战定六荒十海 华夜临危 ...
- jpa 分页
public Page<Stability> testPager(){ Pageable pageable = new PageRequest(1, 10, Sort.Direction. ...
- [LeetCode] 9. 回文数
题目链接:https://leetcode-cn.com/problems/palindrome-number/ 题目描述: 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都 ...
- 一 Struts2 开发流程
SSH与SSM简介SSM:Spring+SpringMVC+MybatisSSH:Struts2+Hibernate+SpringStruts2:是侧重于控制层的框架Hibernate:是一个ORM( ...