题目链接

BZOJ2597

题解

orz思维差

既然是一张竞赛图,我们选出任意三个点都可能成环

总方案数为

\[{n \choose 3}
\]

如果三个点不成环,会发现它们的度数是确定的,入度分别为\(2,1,0\),出度为\(0,1,2\)

所以一个点的任意两个入度,都会对答案产生一个负的贡献

所以三元环数量为

\[{n \choose 3} - \sum\limits_{i = 1}^{n} {inde[i] \choose 2}
\]

我们要最大化三元环数目,就要最小化\(\sum\limits_{i = 1}^{n} {inde[i] \choose 2}\)

考虑建模,使用费用流

每条边可以将入度分给,也仅可以分配给两端点中的一个

我们就每条边建一个点,从\(S\)向每条边建出来的点连一条\((1,0)\)的边,表示能产生一个流量

然后该边的点向那两个端点分别连一条\((1,0)\)的边,表示能产生\(1\)个入度

然后考虑每产生一个入度的影响

考虑到

\[{x \choose 2} - {x - 1 \choose 2} = x - 1
\]

所以每增加一个入度,使得入度为\(x\)时,会多产生\(x - 1\)个贡献

按照费用流的套路,我们对每个点每一种度数建一条到\(T\)的边(1,x - 1),表示消耗这么多三元环

按照费用流的性质,一定会优先选择权值较小的边,也就是逐层增加

建图时,还要考虑原来已有的边

然后就做完了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 11005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int h[maxn],ne = 1;
struct EDGE{int from,to,nxt,f,w;}ed[maxm];
inline void build(int u,int v,int f,int w){
ed[++ne] = (EDGE){u,v,h[u],f,w}; h[u] = ne;
ed[++ne] = (EDGE){v,u,h[v],0,-w}; h[v] = ne;
}
int q[maxn * 10],head,tail;
int p[maxn],vis[maxn],S,T;
int d[maxn],minf[maxn];
int mincost(){
int cost = 0,flow = 0;
while (true){
for (int i = S; i <= T; i++) d[i] = minf[i] = INF,vis[i] = false;
d[S] = 0; q[head = tail = 0] = S;
int u;
while (head <= tail){
u = q[head++];
vis[u] = false;
Redge(u) if (ed[k].f && d[u] + ed[k].w < d[to = ed[k].to]){
minf[to] = min(minf[u],ed[k].f);
p[to] = k; d[to] = d[u] + ed[k].w;
if (!vis[to]) q[++tail] = to,vis[to] = true;
}
}
if (d[T] == INF) break;
flow += minf[T]; cost += d[T] * minf[T];
u = T;
while (u != S){
ed[p[u]].f -= minf[T];
ed[p[u] ^ 1].f += minf[T];
u = ed[p[u]].from;
}
}
return cost;
}
int n,G[105][105],de[105],N,a[maxn],b[maxn];
int main(){
n = read();
REP(i,n) REP(j,n){
G[i][j] = read();
if (i == j) continue;
if (!G[i][j]) de[i]++;
else if (G[i][j] == 2 && i < j) N++,a[N] = i,b[N] = j;
}
S = 0; T = N + n + 1;
REP(i,N) build(S,i,1,0),build(i,N + a[i],1,0),build(i,N + b[i],1,0);
REP(i,n){
for (int j = de[i] + 1; j <= n; j++)
build(N + i,T,1,j - 1);
}
int ans = n * (n - 1) * (n - 2) / 6;
REP(i,n) if (de[i] > 1) ans -= de[i] * (de[i] - 1) / 2;
ans -= mincost();
printf("%d\n",ans);
REP(i,N){
Redge(i) if ((to = ed[k].to) > N && !ed[k].f){
if (to - N == a[i]) G[a[i]][b[i]] = 0,G[b[i]][a[i]] = 1;
else G[a[i]][b[i]] = 1,G[b[i]][a[i]] = 0;
break;
}
}
for (int i = 1; i <= n; i++,puts("")){
for (int j = 1; j <= n; j++){
printf("%d",G[i][j]);
if (j < n) putchar(' ');
}
}
return 0;
}

BZOJ2597 [Wc2007]剪刀石头布 【费用流】的更多相关文章

  1. BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)

    BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...

  2. [WC2007]剪刀石头布——费用流

    比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...

  3. BZOJ 2597: [Wc2007]剪刀石头布(费用流)

    传送门 解题思路 考虑全集-不能构成三元环的个数.如果三个点不能构成三元环,一定有一个点的入度为\(2\),继续扩展,如果一个点的度数为\(3\),则会失去3个三元环.对于一个点来说,它所产生的不能构 ...

  4. bzoj 2597 [Wc2007]剪刀石头布——费用流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 三个人之间的关系,除了“剪刀石头布”,就是有一个人赢了2局:所以考虑算补集,则每个人对 ...

  5. [bzoj2597][Wc2007]剪刀石头布_费用流

    [Wc2007]剪刀石头布 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 题解: 发现直接求三元环不好求,我们考虑任选三个点不是 ...

  6. bzoj2597: [Wc2007]剪刀石头布(费用流)

    传送门 不得不说这思路真是太妙了 考虑能构成三元组很难,那我们考虑不能构成三元组的情况是怎么样 就是说一个三元组$(a,b,c)$,其中$a$赢两场,$b$赢一场,$c$没有赢 所以如果第$i$个人赢 ...

  7. Luogu4249 WC2007 石头剪刀布 费用流

    传送门 考虑竞赛图三元环计数,设第\(i\)个点的入度为\(d_i\),根据容斥,答案为\(C_n^3 - \sum C_{d_i}^2\) 所以我们需要最小化\(\sum C_{d_i}^2\) 考 ...

  8. BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)

    题目大概是说n个人两两进行比赛,问如何安排几场比赛的输赢使得A胜B,B胜C,C胜A这种剪刀石头布的三元组最多. 这题好神. 首先,三元组总共有$C_n^3$个 然后考虑最小化不满足剪刀石头布条件的三元 ...

  9. BZOJ2597 WC2007剪刀石头布(费用流)

    考虑使非剪刀石头布情况尽量少.设第i个人赢了xi场,那么以i作为赢家的非剪刀石头布情况就为xi(xi-1)/2种.那么使Σxi(xi-1)/2尽量小即可. 考虑网络流.将比赛建成一排点,人建成一排点, ...

随机推荐

  1. Xuan.UWP.Framework(2)

    上一章主要介绍了Xuan.UWP.Framework.ImageLib的基本用法,这一章具体来看些Xuan.UWP.Framework.ImageLib的使用. 一.首先看下Xuan.UWP.Fram ...

  2. DirectX11与DirectX12在古墓丽影暗影中的表现

    最近在关注这两个图形API,因为感兴趣,也算是初学者. 以下内容仅供参考. 使用古墓丽影暗影游戏,分别对这两个进行比较,得出的结论如下图(此笔记本散热很差,更改散热应该比下图结果好些): 首先看可以很 ...

  3. MySQL☞abs函数

    abs( )函数:求出绝对值 格式: select  abs(数值)  from 表名 如下图:

  4. 基于Python的接口自动化

    第一步 Python的安装配置 打开官网: https://www.python.org/downloads/ 目前官网上已经更新到3.6.1啦,有两个版本,大家可以按自己喜欢的去下载,我自己选择的是 ...

  5. [CodeForce455A]Boredom

    题面描述 Alex doesn't like boredom. That's why whenever he gets bored, he comes up with games. One long ...

  6. VBS简明教程

    VBS简明教程   一.输出 VBS的输出使用函数Msgbox调用对话框进行输出. Msgbox(message) Message为要输出的信息 二.输入 VBS的输入,调用函数Inputbox()进 ...

  7. Python实现个性化推荐一

    现如今,网站用推荐系统为你提供个性化的体验,告诉你买啥,吃啥甚至你应该和谁交朋友.尽管每个人口味不同,但大体都适用这个套路.人们倾向于喜欢那些与自己喜欢的其他东西相似的东西,也倾向于与自己身边的人有相 ...

  8. IMX6移植htop

    top命令查看CPU利用率并不是很方便,因此打算移植htop到imx6上,主要包括以下几个步骤: - 资源下载 htop 下载http://hisham.hm/htop/releases/1.0.1/ ...

  9. Python中变量名里面的下划线

    1 变量名前后都有两个下划线(__X__),表示是系统级变量: 2 变量名前只有一个下划线(_X),表示该变量不是由from module import *导入进来的: 3 变量名前有两个下划线(__ ...

  10. Thunder团队第五周 - Scrum会议3

    Scrum会议3 小组名称:Thunder 项目名称:i阅app Scrum Master:王航 工作照片: 苗威同学在拍照,所以不在照片内. 参会成员: 王航(Master):http://www. ...