[bzoj2597][WC2007]剪刀石头布
来源:互联网 发布:淘宝 装修日记 编辑:程序博客网 时间:2024/05/17 01:19
2597: [Wc2007]剪刀石头布
Time Limit: 20 Sec Memory Limit: 128 MBSec Special Judge
Submit: 732 Solved: 350
[Submit][Status][Discuss]
Description
在一些一对一游戏的比赛(如下棋、乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况。有的时候,无聊的人们会津津乐道于统计有多少这样的剪刀石头布情况发生,即有多少对无序三元组(A, B, C),满足其中的一个人在比赛中赢了另一个人,另一个人赢了第三个人而第三个人又胜过了第一个人。注意这里无序的意思是说三元组中元素的顺序并不重要,将(A, B, C)、(A, C, B)、(B, A, C)、(B, C, A)、(C, A, B)和(C, B, A)视为相同的情况。
有N个人参加一场这样的游戏的比赛,赛程规定任意两个人之间都要进行一场比赛:这样总共有场比赛。比赛已经进行了一部分,我们想知道在极端情况下,比赛结束后最多会发生多少剪刀石头布情况。即给出已经发生的比赛结果,而你可以任意安排剩下的比赛的结果,以得到尽量多的剪刀石头布情况。
Input
输入文件的第1行是一个整数N,表示参加比赛的人数。
之后是一个N行N列的数字矩阵:一共N行,每行N列,数字间用空格隔开。
在第(i+1)行的第j列的数字如果是1,则表示i在已经发生的比赛中赢了j;该数字若是0,则表示在已经发生的比赛中i败于j;该数字是2,表示i和j之间的比赛尚未发生。数字矩阵对角线上的数字,即第(i+1)行第i列的数字都是0,它们仅仅是占位符号,没有任何意义。
输入文件保证合法,不会发生矛盾,当i≠j时,第(i+1)行第j列和第(j+1)行第i列的两个数字要么都是2,要么一个是0一个是1。
Output
输出文件的第1行是一个整数,表示在你安排的比赛结果中,出现了多少剪刀石头布情况。
输出文件的第2行开始有一个和输入文件中格式相同的N行N列的数字矩阵。第(i+1)行第j个数字描述了i和j之间的比赛结果,1表示i赢了j,0表示i负于j,与输入矩阵不同的是,在这个矩阵中没有表示比赛尚未进行的数字2;对角线上的数字都是0。输出矩阵要保证合法,不能发生矛盾。
Sample Input
3
0 1 2
0 0 2
2 2 0
Sample Output
1
0 1 0
0 0 1
1 0 0
HINT
100%的数据中,N≤ 100。
首先可以用容斥原理计算出答案:
前面的表示所有的组合,后面减去了不是三元环的情况,因为如果不是三元环,那么肯定有一个点的初度是2,所以用后面的式子就可以算出不是三元环的数量。
上面的那个式子化简一下就变成了
前面的两项是已知的,所以问题就转化成了求最后面那个式子的最小值。
这样就可以用费用流做了。对于费用是平方的问题,我们可以建多条变,权值分别为1,3,5…,这样最小费用的话肯定是先跑费用小的边,跑完之后就是平方得形式。
建图的时候需要保证从i赢了j,j就不能再赢i了。
所以对于每一对点i,j我们都建立一个代表这个点对的点,从原点向这个点连(1,0)的边,从这个点向i,j连(1,0)的边。
最后从每个点向汇点连n-1条(1,x)的边,其中x是上面说的那个等差数列。
#include<cstdio>using namespace std;#include<iostream>#include<cstring>#define D 100000#define T n*n+n+2#define inf 707406378const int N=110;const int M=100010;bool f[M];struct S{int st,en,va,co;}aa[M*10];int n,point[M],next[M*10],dis[M],pre[M],map[N][N],win[N],tot=1,l[M];inline void add(int x,int y,int va,int co){ next[++tot]=point[x];point[x]=tot; aa[tot].st=x;aa[tot].en=y;aa[tot].va=va;aa[tot].co=co; next[++tot]=point[y];point[y]=tot; aa[tot].st=y;aa[tot].en=x;aa[tot].va=0;aa[tot].co=-co;}inline int SPFA(int x,int y){ int i,j,u,h,t; memset(f,1,sizeof(f)); memset(dis,127/3,sizeof(dis)); h=0;t=1;l[t]=x;dis[x]=0; while(h!=t){ h=h%D+1;u=l[h];f[u]=true; for(i=point[u];i;i=next[i]) if(dis[aa[i].en]>dis[u]+aa[i].co&&aa[i].va>0){ dis[aa[i].en]=dis[u]+aa[i].co; pre[aa[i].en]=i; if(f[aa[i].en]){ f[aa[i].en]=false; t=t%D+1; l[t]=aa[i].en; } } } return dis[y]==inf?0:dis[y];}inline int ISAP(int x,int y){ int i,minn=inf; for(i=y;i!=x;i=aa[pre[i]].st) minn=min(minn,aa[pre[i]].va); for(i=y;i!=x;i=aa[pre[i]].st){ aa[pre[i]].va-=minn; aa[pre[i]^1].va+=minn; } return minn;}int main(){ int i,j,x,k; scanf("%d",&n); for(i=1;i<=n;++i){ for(j=1;j<=n;++j){ scanf("%d",&x);map[i][j]=x; if(i==j) continue; if(x==1) ++win[i]; if(x==2&&i<j){ add(1,(i-1)*n+j+1,1,0); add((i-1)*n+j+1,i+n*n+1,1,0); add((i-1)*n+j+1,j+n*n+1,1,0); } } for(j=win[i]+1;j<=n;++j) add(i+n*n+1,T,1,j*2-1); } int ans=0,minn=1; while(minn){ minn=SPFA(1,T); if(minn) ans+=minn*ISAP(1,T); } for(i=1;i<=n;++i) for(j=i+1;j<=n;++j) if(map[i][j]==2) for(k=point[(i-1)*n+j+1];k;k=next[k]) if(aa[k].va==0){ if(aa[k].en==i+n*n+1) map[i][j]=1,map[j][i]=0,++win[i]; if(aa[k].en==j+n*n+1) map[j][i]=1,map[i][j]=0,++win[j]; } ans=n*(n-1)*(n-2)/6; for(i=1;i<=n;++i) ans-=win[i]*(win[i]-1)/2; printf("%d\n",ans); for(i=1;i<=n;++i){ for(j=1;j<=n;++j) printf("%d ",map[i][j]); printf("\n"); }}
- bzoj2597【WC2007】剪刀石头布
- [bzoj2597][WC2007]剪刀石头布
- 【WC2007】bzoj2597 剪刀石头布
- bzoj2597: [Wc2007]剪刀石头布
- BZOJ2597: [Wc2007]剪刀石头布
- 【bzoj2597】[Wc2007]剪刀石头布 费用流
- bzoj1449: [JSOI2009]球队收益&&bzoj2597: [Wc2007]剪刀石头布
- [BZOJ2597][Wc2007]剪刀石头布(费用流)
- BZOJ2597: [Wc2007]剪刀石头布(费用流)
- 【BZOJ2597】【Wc2007】剪刀石头布 费用流,没写zkw卡时过
- 【BZOJ 2597】 [Wc2007]剪刀石头布
- 2597: [Wc2007]剪刀石头布 费用流
- 1449: [JSOI2009]球队收益 和 2597: [Wc2007]剪刀石头布
- 【BZOJ】【P2597】【Wc2007】【剪刀石头布】【题解】【费用流】
- BZOJ 2597 WC2007 剪刀石头布 费用流
- BZOJ 2597 WC2007 剪刀石头布 费用流
- BZOJ 2597: [Wc2007]剪刀石头布|费用流
- bzoj 2597: [Wc2007]剪刀石头布(费用流)
- Android Studio——gradle配置(基本知识)
- 基本算法分类与原理
- Ubuntu 安装 MongoDb
- jquery 获得table中所有行的数据
- Mysql常用函数
- [bzoj2597][WC2007]剪刀石头布
- 52.View the Exhibit and examine the structure of the PRODUCTS table.
- 物理仿真UIDynamic 介绍 (吸附行为)(推动行为) (一)
- 华为oj 计算日期到天数转换
- 2015年上半年系统分析师试题(附答案)
- 入门Android开发--笔记--SharedPrefrence存储、读对象
- Ruby on Rails 3 Can't connect to local MySQL server through socket '/tmp/mysql.sock' on linux
- 信息更新小红点显示——自定义控件BadgeView的使用介绍
- Pseudo-Random Numbers