[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$个 然后考虑最小化不满足剪刀石头布条件的三元 ...
随机推荐
- Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法
前言: 今天我想把百度地图的定位集成到项目中来,想写个小小的案例,实现一下,但在集成百度地图时首先要申请秘钥,申请秘钥要用到SHA1值,所以今天就来总结一下怎样去获取这个值吧,希望对大家有帮助. 正常 ...
- Visual Studio 无法记忆标签页、断点等的解决办法
1.到工程目录删除*.suo文件 2.*.suo默认是隐藏的,需要打开查看隐藏文件的开关
- 如何在MongoDB设计存储你的数据(JSON化)?
第一步 定义要描述的数据集 当我们决定将数据存储下来的时候,我们首先要回答的一个问题就是:“我打算存储什么样的数据?这些数据之间有什么关系?实体之间有什么关系?实体的属性之间有什么关系”. 为了说明问 ...
- AES 加密与解密
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Securit ...
- 数据库【mysql篇】典型的一些练习题目
班级表 class 学生表student 老师表 teacher 课程表course 成绩表 score 准备数据 创建数据库 create database tang_test charset='u ...
- HBase Client JAVA API
旧 的 HBase 接口逻辑与传统 JDBC 方式很不相同,新的接口与传统 JDBC 的逻辑更加相像,具有更加清晰的 Connection 管理方式. 同时,在旧的接口中,客户端何时将 Put 写到服 ...
- Flink Pre-defined Timestamp Extractors / Watermark Emitters(预定义的时间戳提取/水位线发射器)
https://ci.apache.org/projects/flink/flink-docs-release-1.6/dev/event_timestamp_extractors.html 根据官网 ...
- winserver的consul部署实践与.net core客户端使用(附demo源码)
winserver的consul部署实践与.net core客户端使用(附demo源码) 前言 随着微服务兴起,服务的管理显得极其重要.都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的 ...
- Spring Security(三十六):12. Spring MVC Test Integration
Spring Security provides comprehensive integration with Spring MVC Test Spring Security提供与Spring MVC ...
- Redis入门---字符串类型
阅读目录 1.keys * 命令 2.判断一个键是否存在(exists key) 3.删除键 4.获取键值的数据类型 5 递增数字(incr) 6.增加指定的整数 (INCRBY) 7.减少指定的整数 ...