Luogu4249 WC2007 石头剪刀布 费用流
考虑竞赛图三元环计数,设第\(i\)个点的入度为\(d_i\),根据容斥,答案为\(C_n^3 - \sum C_{d_i}^2\)
所以我们需要最小化\(\sum C_{d_i}^2\)
考虑将\(C_{d_i}^2\)差分,然后通过费用流解决
下面\((a,b)\)边表示流量为\(a\)、费用为\(b\)的边
建图:
每一场比赛和每一个人都建一个点
\(S\)向每一场比赛连\((1,0)\)边
每一场比赛若不确定结果则向两个参与者连\((1,0)\)边,如果胜者确定则只向胜者连\((1,0)\)边
每一个选手向\(T\)连\((1,C_i^2-C_{i-1}^2)(i \in [1,N])\)边
因为\(C_i^2-C_{i-1}^2=i-1\),所以\(j>i \rightarrow C_j^2 - C_{j-1}^2 > C_i^2 - C_{i-1}^2\),所以每一次一场比赛确定胜者能够正确地增加TA的贡献。
跑最小费用最大流,最后的答案就是最小的\(\sum C_{d_i}^2\)
输出方案考虑每一场比赛对应的点的流流向哪一个选手即可
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
}
const int MAXN = 20010 , MAXM = 500010;
struct Edge{
int end , upEd , f , c;
}Ed[MAXM];
int head[MAXN] , dis[MAXN] , pre[MAXN] , flo[MAXN] , ans[110][110];
int N , S , T , cntEd = 1;
bool vis[MAXN];
queue < int > q;
inline void addEd(int a , int b , int c , int d = 0){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
Ed[cntEd].f = c;
Ed[cntEd].c = d;
head[a] = cntEd;
}
inline bool SPFA(){
memset(dis , 0x3f , sizeof(dis));
dis[S] = 0;
while(!q.empty())
q.pop();
q.push(S);
flo[S] = INF;
while(!q.empty()){
int t = q.front();
q.pop();
vis[t] = 0;
for(int i = head[t] ; i ; i = Ed[i].upEd)
if(Ed[i].f && dis[Ed[i].end] > dis[t] + Ed[i].c){
dis[Ed[i].end] = dis[t] + Ed[i].c;
flo[Ed[i].end] = min(Ed[i].f , flo[t]);
pre[Ed[i].end] = i;
if(!vis[Ed[i].end]){
vis[Ed[i].end] = 1;
q.push(Ed[i].end);
}
}
}
return dis[T] != dis[T + 1];
}
int EK(){
int ans = 0;
while(SPFA()){
int cur = T , sum = 0;
while(cur != S){
sum += Ed[pre[cur]].c;
Ed[pre[cur]].f -= flo[T];
Ed[pre[cur] ^ 1].f += flo[T];
cur = Ed[pre[cur] ^ 1].end;
}
ans += sum * flo[T];
}
return ans;
}
void input(){
N = read();
int cnt = N;
for(int i = 1 ; i <= N ; ++i){
for(int j = 1 ; j <= i ; ++j)
read();
for(int j = i + 1 ; j <= N ; ++j){
int a = read();
addEd(S , ++cnt , 1);
addEd(cnt , S , 0);
if(a != 1){
addEd(cnt , j , 1);
addEd(j , cnt , 0);
}
if(a){
addEd(cnt , i , 1);
addEd(i , cnt , 0);
}
}
}
T = ++cnt;
for(int i = 1 ; i <= N ; ++i)
for(int j = 1 ; j <= N ; ++j){
addEd(i , T , 1 , j * (j - 1) / 2 - (j - 1) * (j - 2) / 2);
addEd(T , i , 0 , -(j * (j - 1) / 2 - (j - 1) * (j - 2) / 2));
}
}
void work(){
cout << N * (N - 1) * (N - 2) / 6 - EK() << endl;
int cnt = N;
for(int i = 1 ; i <= N ; ++i)
for(int j = 1 ; j <= N ; ++j)
if(i != j)
if(i > j)
ans[i][j] = ans[j][i] ^ 1;
else{
++cnt;
for(int k = head[cnt] ; k ; k = Ed[k].upEd)
if(!Ed[k].f){
ans[i][j] = Ed[k].end == i;
break;
}
}
for(int i = 1 ; i <= N ; ++i){
for(int j = 1 ; j <= N ; ++j)
cout << ans[i][j] << ' ';
cout << endl;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in" , "r" , stdin);
//freopen("out" , "w" , stdout);
#endif
input();
work();
return 0;
}
Luogu4249 WC2007 石头剪刀布 费用流的更多相关文章
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...
- [WC2007]剪刀石头布——费用流
比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...
- BZOJ 2597: [Wc2007]剪刀石头布(费用流)
传送门 解题思路 考虑全集-不能构成三元环的个数.如果三个点不能构成三元环,一定有一个点的入度为\(2\),继续扩展,如果一个点的度数为\(3\),则会失去3个三元环.对于一个点来说,它所产生的不能构 ...
- bzoj 2597 [Wc2007]剪刀石头布——费用流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 三个人之间的关系,除了“剪刀石头布”,就是有一个人赢了2局:所以考虑算补集,则每个人对 ...
- WC2007 石头剪刀布 数学+最小费用最大流
题面: 有N个人参加一场比赛,赛程规定任意两个人之间都要进行一场比赛:这样总共有N*(N-1)/2场比赛.比赛已经进行了一部分,我们想知道在极端情况下,比赛结束后最多会发生多少剪刀石头布情况.即给出已 ...
- [bzoj2597][Wc2007]剪刀石头布_费用流
[Wc2007]剪刀石头布 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 题解: 发现直接求三元环不好求,我们考虑任选三个点不是 ...
- BZOJ2597 [Wc2007]剪刀石头布 【费用流】
题目链接 BZOJ2597 题解 orz思维差 既然是一张竞赛图,我们选出任意三个点都可能成环 总方案数为 \[{n \choose 3}\] 如果三个点不成环,会发现它们的度数是确定的,入度分别为\ ...
- bzoj2597: [Wc2007]剪刀石头布(费用流)
传送门 不得不说这思路真是太妙了 考虑能构成三元组很难,那我们考虑不能构成三元组的情况是怎么样 就是说一个三元组$(a,b,c)$,其中$a$赢两场,$b$赢一场,$c$没有赢 所以如果第$i$个人赢 ...
- 【bzoj2597】[Wc2007]剪刀石头布 动态加边费用流
题目描述 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道于统计有多少这 ...
随机推荐
- Linux 时间及时区设置
时间以及时区设置 by:授客 QQ:1033553122 1.首先确认使用utc还是local time. UTC(Universal Time Coordinated)=GMT(Greenwich ...
- Login case
第一步:画UI,代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ...
- vue 环境的搭建及初始化项目
其实超级简单,虽然网上很多,但是我顺便记录下相当于做笔记吧 1nodejs 的安装, 在node官网下载,点击安装,安装的时候最好选择路径在d盘 2设置环境变量 我的电脑-->属性-->系 ...
- 【CSS基础】实现 div 里的内容垂直水平居中
方案一: 所有内容垂直水平居中 兼容性:IE8+. 条件:内容宽度和高度可以未知,可以是多行文字.图片.div. 描述:使用table-cell + vertical-align , html代码见文 ...
- [20180608]Wrong Results with IOT, Added Column and Secondary Index.txt
[20180608]Wrong Results with IOT, Added Column and Secondary Index.txt --//链接:http://db-oriented.com ...
- asp.net根据参数找不到记录后响应404及显示错误页
在asp.net mvc 中,action方法里根据参数获取数据,假如获取的数据为空,为了响应404错误页,我们可以return HttpNotFound(); 但是在asp.net webform中 ...
- Fedora 29 使用 SCL (Software Collections)
在社区中SCL 由Centos 项目进行维护,所以我们使用CentOS 7 SCL源.CentOS SCL中提供了devtoolset-7-gcc-c++,版本正好为 gcc version 7.3. ...
- 用Python做股市数据分析(一)
本文由 伯乐在线 - 小米云豆粥 翻译.未经许可,禁止转载!英文出处:Curtis Miller.欢迎加入翻译组. 这篇博文是用Python分析股市数据系列两部中的第一部,内容基于我犹他大学 数学39 ...
- [MapReduce_add_2] MapReduce 实现年度最高气温统计
0. 说明 编写 MapReduce 程序实现年度最高气温统计 1. 气温数据分析 气温数据样例如下: ++023450FM-+000599999V0202701N015919999999N00000 ...
- SQL 三范式
第一范式:无重复的列,一列只能包含一个字段 第二范式:主键约束,一行只能被唯一标识 第三范式:非主键字段要严格依赖于主键字段