传送门

不得不说这思路真是太妙了

考虑能构成三元组很难,那我们考虑不能构成三元组的情况是怎么样

就是说一个三元组$(a,b,c)$,其中$a$赢两场,$b$赢一场,$c$没有赢

所以如果第$i$个人赢了$w_i$场,那么总共的不能构成的三元组就是$\sum_i{w_i*(w_i-1)}{2}$

最大化满足的数量,就是最小化不满足的数量,就是最小化上面那个式子

那么我们考虑构建网络流

建源汇

对第$i$个人,从它向汇点连容量为$n$的边

对于每一对$i,j$之间的比赛建一个点$C_{i,j}$,如果这场比赛尚未进行,那么源点向$C_{i,j}$连容$1$费$0$的边,$C_{i,j}向$i$和$j$连容$1$费$0$的边,表示这场比赛只能改变一个点的赢的场数

我们要最小化上式,那么我们考虑在费用上做文章

每个点$i$向汇点连边,但因为费用的增加是一次比一次大的,所以我们考虑把这条边拆成$n$条边,容量为$1$费用分别为$0,1,2...$

因为费用流每一次都先增广最小的费用,所以只要求出最小费用最大流即可

 //minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int head[N],Next[M],ver[M],edge[M],cost[M],tot=;
inline void add(int u,int v,int e,int c=){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e,cost[tot]=c;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=,cost[tot]=-c;
}
int dis[N],vis[N],cur[N],S,T,ans;
queue<int> q;
bool spfa(){
memset(dis,-,sizeof(dis));
memset(vis,,sizeof(vis));
memcpy(cur,head,sizeof(head));
q.push(T),dis[T]=,vis[T]=;
while(!q.empty()){
int u=q.front();q.pop(),vis[u]=;
for(int i=head[u];i;i=Next[i])
if(edge[i^]){
int v=ver[i],c=cost[i];
if(dis[v]<||dis[v]>dis[u]-c){
dis[v]=dis[u]-c;
if(!vis[v]) vis[v]=,q.push(v);
}
}
}
return ~dis[S];
}
int dfs(int u,int limit){
if(!limit||u==T) return limit;
int flow=,f;vis[u]=;
for(int i=cur[u];i;cur[u]=i=Next[i]){
int v=ver[i];
if(dis[v]==dis[u]-cost[i]&&!vis[v]&&(f=dfs(v,min(limit,edge[i])))){
flow+=f,limit-=f;
edge[i]-=f,edge[i^]+=f;
ans-=f*cost[i];
if(!limit) break;
}
}
vis[u]=;
return flow;
}
void zkw(){while(spfa()) dfs(S,inf);}
int mp[][],win[][],n,cnt;
int main(){
//freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
mp[i][j]=read();
S=,cnt=n;
for(int i=;i<=n;++i)
for(int j=;j<i;++j){
add(S,++cnt,);
if(mp[i][j]==||mp[i][j]==) add(cnt,i,),win[j][i]=tot-;
if(mp[i][j]==||mp[i][j]==) add(cnt,j,),win[i][j]=tot-;
}
T=cnt+;
for(int i=;i<=n;++i)
for(int j=;j<n;++j)
add(i,T,,j);
ans=n*(n-)*(n-)/;
zkw();
printf("%d\n",ans);
for(int i=;i<=n;++i){
for(int j=;j<=n;++j)
printf("%s%d",j==?"":" ",!win[i][j]||edge[win[i][j]]?:);
putchar();
}
return ;
}

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]剪刀石头布 【费用流】

    题目链接 BZOJ2597 题解 orz思维差 既然是一张竞赛图,我们选出任意三个点都可能成环 总方案数为 \[{n \choose 3}\] 如果三个点不成环,会发现它们的度数是确定的,入度分别为\ ...

  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. 数据库的join查询

    假设我们有两张表. Table A 是左边的表. Table B 是右边的表. 其各有四条记录,其中有两条记录是相同的,如下所示: id name id name -- ---- -- ---- 1 ...

  2. PS 滤镜— —Twirl Filter

    clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorithm'); I=imread ...

  3. 判断浏览器是否支持css3属性或单位

    1.用CSS.supports()方法 mark-zhq[3] //判断是否支持flex布局 var supportsFlex = CSS.supports("display", ...

  4. ffmpeg编码h264只包含I帧P帧的方法

    ffmpeg使用avcodc_encode_video编码,默认产生的h264包含B帧,在安防行业很多地方是不需要用到B帧的. 1.基础知识充电 这就涉及到h264的各种profile格式了,参考 h ...

  5. javascript获取窗口位置、绝对位置、事件位置等

    有段时间没更新博客了,工作实在太忙了,加班加班再加班就是我们这个行业的常态吧...还好最近把工作进度完成了,终于有些空余时间了.关于<Javascript高级程序设计>系列,我并没有弃坑, ...

  6. [Codeforces 204E] Little Elephant and Strings

    [题目链接] https://codeforces.com/contest/204/problem/E [算法] 首先构建广义后缀自动机 对于自动机上的每个节点 , 维护一棵平衡树存储所有它所匹配的字 ...

  7. unity渲染层级关系小结

    http://blog.csdn.net/meegomeego/article/details/42060389 最近连续遇到了几个绘制图像之间相互遮挡关系不正确的问题,网上查找的信息比较凌乱,所以这 ...

  8. 系列文章--8天学通MongoDB

    随笔分类 - MongoDB 8天学通MongoDB——第八天 驱动实践 摘要: 作为系列的最后一篇,得要说说C#驱动对mongodb的操作,目前驱动有两种:官方驱动和samus驱动,不过我个人还是喜 ...

  9. C语言学习笔记--struct 和 union关键字

    1.struct关键字 C 语言中的 struct 可以看作变量的集合struct中的每个数据成员都有独立的存储空间. 结构体与柔性数组 (1)柔性数组即数组大小待定的数组 (2)C 语言中可以由结构 ...

  10. Javascript作用域和变量提升

    下面的程序是什么结果? var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); 结果是10: 那么 ...