【BZOJ2597】[Wc2007]剪刀石头布 最小费用流
【BZOJ2597】[Wc2007]剪刀石头布
Description
Input
Output
Sample Input
0 1 2
0 0 2
2 2 0
Sample Output
0 1 0
0 0 1
1 0 0
HINT
100%的数据中,N≤ 100。
题解:看到数据范围和大致题意想到了网络流(并且是拆边的那种),然后正着做不出来想到反着做,然而自己太弱了反着做都做不出来,于是看大爷的题解,秒懂。
为了建图,首先我们想象原图是一张竞赛图(任意两点之间有一条有向边相连),我们要给部分边定向,使得形成的三元环尽可能多。我们考虑每个三元组,如果不能形成环,当且仅当一个点的出度=2。所以,一个点的每两个出度就对应了失去的一个三元环。所以总环数=$C_n^3-\sum C_{d[i]}^2$。然后$C_{d[i]}^2={d[i]*(d[i]-1)\over 2}$,差分一下就会发现一个点每次d[i]++,就要失去d[i]-1个三元环。所以我们想到以出度为流量,构建最小费用最大流模型。
建图部分其实很简单,不具体解释了,直接上连边方法:
1.S->每条无向边 费用0,容量1
2.每条无向边->它的两个顶点 费用0,容量1
3.每个点->T 连若干条边,其中第i条费用i-1,容量1
至于原图中的有向边,特判一下就好了。输出方案什么的,自己搞一搞吧~
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
int n,cnt,S,T,tot,ans;
int to[1000000],next[1000000],cost[1000000],flow[1000000],dis[10000],inq[10000],pe[10000],pv[10000],head[10000];
int d[110],res[110][110];
queue<int> q;
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void add(int a,int b,int c,int d)
{
to[cnt]=b,cost[cnt]=c,flow[cnt]=d,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,cost[cnt]=-c,flow[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
int bfs()
{
memset(dis,0x3f,sizeof(dis));
int i,u;
q.push(S),dis[S]=0;
while(!q.empty())
{
u=q.front(),q.pop(),inq[u]=0;
for(int i=head[u];i!=-1;i=next[i])
{
if(dis[to[i]]>dis[u]+cost[i]&&flow[i])
{
dis[to[i]]=dis[u]+cost[i],pe[to[i]]=i,pv[to[i]]=u;
if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
}
}
}
return dis[T]<0x3f3f3f3f;
}
int main()
{
n=rd(),S=0,T=tot=n+1;
int i,j,a,mf;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
a=rd();
if(i>=j) continue;
if(a==2) res[i][j]=cnt+3,add(S,++tot,0,1),add(tot,i,0,1),add(tot,j,0,1),add(i,T,d[i]++,1),add(j,T,d[j]++,1);
if(a==1) res[i][j]=-1,add(S,i,0,1),add(i,T,d[i]++,1);
if(a==0) res[i][j]=-2,add(S,j,0,1),add(j,T,d[j]++,1);
}
}
ans=n*(n-1)*(n-2)/6;
while(bfs())
{
mf=1<<30;
for(i=T;i!=S;i=pv[i]) mf=min(mf,flow[pe[i]]);
ans-=dis[T]*mf;
for(i=T;i!=S;i=pv[i]) flow[pe[i]]-=mf,flow[pe[i]^1]+=mf;
}
printf("%d\n",ans);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(j!=1) printf(" ");
if(i>j) printf("%d",res[j][i]^1);
else if(i==j) printf("0");
else
{
if(res[i][j]==-1) res[i][j]=1;
else if(res[i][j]==-2) res[i][j]=0;
else res[i][j]=flow[res[i][j]];
printf("%d",res[i][j]);
}
}
printf("\n");
}
return 0;
}
【BZOJ2597】[Wc2007]剪刀石头布 最小费用流的更多相关文章
- [bzoj2597][Wc2007]剪刀石头布_费用流
[Wc2007]剪刀石头布 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 题解: 发现直接求三元环不好求,我们考虑任选三个点不是 ...
- BZOJ2597 WC2007剪刀石头布(费用流)
考虑使非剪刀石头布情况尽量少.设第i个人赢了xi场,那么以i作为赢家的非剪刀石头布情况就为xi(xi-1)/2种.那么使Σxi(xi-1)/2尽量小即可. 考虑网络流.将比赛建成一排点,人建成一排点, ...
- BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)
题目大概是说n个人两两进行比赛,问如何安排几场比赛的输赢使得A胜B,B胜C,C胜A这种剪刀石头布的三元组最多. 这题好神. 首先,三元组总共有$C_n^3$个 然后考虑最小化不满足剪刀石头布条件的三元 ...
- bzoj2597: [Wc2007]剪刀石头布
Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道 ...
- BZOJ2597 [Wc2007]剪刀石头布 【费用流】
题目链接 BZOJ2597 题解 orz思维差 既然是一张竞赛图,我们选出任意三个点都可能成环 总方案数为 \[{n \choose 3}\] 如果三个点不成环,会发现它们的度数是确定的,入度分别为\ ...
- bzoj2597: [Wc2007]剪刀石头布(费用流)
传送门 不得不说这思路真是太妙了 考虑能构成三元组很难,那我们考虑不能构成三元组的情况是怎么样 就是说一个三元组$(a,b,c)$,其中$a$赢两场,$b$赢一场,$c$没有赢 所以如果第$i$个人赢 ...
- 【BZOJ-2597】剪刀石头布 最小费用最大流
2597: [Wc2007]剪刀石头布 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1016 Solved: ...
- [Wc2007]剪刀石头布
[Wc2007]剪刀石头布 http://www.lydsy.com/JudgeOnline/problem.php?id=2597 Time Limit: 20 Sec Memory Limit: ...
- 2597: [Wc2007]剪刀石头布
2597: [Wc2007]剪刀石头布 链接 分析: 费用流. 首先转化一下问题,整张图最优的情况是存在$C_n^3$个,即任意3个都行,然后考虑去掉最少不满足的三元环. 如果u赢了v,u向v连一条边 ...
随机推荐
- ViewAnimator实现复杂的动画效果
咱们先看个原生的 AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( ObjectAnimator.ofFlo ...
- 第十二届北航程序设计竞赛决赛网络同步赛 J题 两点之间
题目链接 Problem J 这道题思路还是很直观的,但是有两个难点: 1.题目中说$1<=NM<=10^{6}$,但没具体说明$N$和$M$的值,也就是可能出现: $N = 1, M ...
- MapReduce编程模型及其在Hadoop上的实现
转自:https://www.zybuluo.com/frank-shaw/note/206604 MapReduce基本过程 关于MapReduce中数据流的传输过程,下图是一个经典演示: 关于上 ...
- Office 2016 安装你所必须要注意的事项
坑主要是,Office 2016专业增强不能自定义安装路径,不能选择需要安装的产品组件(不能取消outlook, onenote等垃圾组件). 软件的下载可以在百度上搜索,cn_office_prof ...
- hdu1420(C++)
数论中模的运算: a*b%n=(a%n)*(b%n)%c; (a+b)%n=(a%n+b%n)%n; 幂的模:A^n%c=r 于是A^(n+1)%c=A*r%c; #include<ios ...
- C++面试试题汇总1
1.C和C++的主要区别是什么? 答:1.C++语言包括过程性语言部分和类部分,过程性语言部分与C并无本质的差别,类部分是C语言中所没有的,它是面向对象程序设计的主体. 2.程序设计方法上已从结构化程 ...
- HTML5 Canvas 绘制星条旗
代码: <!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type ...
- AudioSession/AudioCaptureSession的分析与使用
这个是AudioSession的结构图: 前一个部分已经介绍了AVFoundation对音频录制.播放的一种方法,以下再介绍第二种: AVCaptureSession 用这个类的长处在什么地方呢? ( ...
- 为什么我们有时不用配置java环境变量?
答案都在这个图中 完毕,如果还不懂请自行查询注册表相关内容学习.
- 关于 html 中 table 表格 tr,td 的高度和宽度
http://wenku.baidu.com/link?url=76BZcBS3YyA1QJwE7pCPJKERPex4uSQEQ1LI5ZkwTCtunw2cBTaLI8E71dxUhFW0CH4h ...