[Wc2007]剪刀石头布

http://www.lydsy.com/JudgeOnline/problem.php?id=2597

Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special Judge

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,表示参加比赛的人数。
之后是一个NN列的数字矩阵:一共N行,每行N列,数字间用空格隔开。
在第(i+1)行的第j列的数字如果是1,则表示i在已经发生的比赛中赢了j;该数字若是0,则表示在已经发生的比赛中i败于j;该数字是2,表示ij之间的比赛尚未发生。数字矩阵对角线上的数字,即第(i+1)行第i列的数字都是0,它们仅仅是占位符号,没有任何意义。
输入文件保证合法,不会发生矛盾,当ij时,第(i+1)行第j列和第(j+1)行第i列的两个数字要么都是2,要么一个是0一个是1。

Output

输出文件的第1行是一个整数,表示在你安排的比赛结果中,出现了多少剪刀石头布情况。
输出文件的第2行开始有一个和输入文件中格式相同的NN列的数字矩阵。第(i+1)行第j个数字描述了ij之间的比赛结果,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
 
首先最多的合法三元组转化为最少的不合法三元组
每个三元组中,不合法的情况是胜利者有2条出边
所以每个人对不合法三元组的贡献是C(win[i],2)
win[i]表示i的胜利次数
ans=C(n,3)- Σ (win[i],2)
所以最小化 Σ (win[i],2)
考虑最小费用流
C(1,2)=0
C(2,2)=1
C(3,2)=3
C(4,2)=6
每次对答案的贡献一次+1、+2、+3、+4……
所以构图方式:
首先累加已知的Σ C(win[i],2)
源点向每一场比赛连流量为1、费用为0的边
这场比赛如果已知结果,向胜利者连流量为1、费用为0的边
如果不知道结果,向两人都连流量为1、费用为0的边
对于每个人,都向汇点连n-1条边,前win[i]条流量为1,费用为0
                其余的流量为1,费用为win[i]、win[i]+1、win[i]+2……
  1. #include<queue>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define N 5500
  5. #define M 50000
  6. using namespace std;
  7. int win[],cnt;
  8. int src,decc;
  9. int front[N],nxt[M],to[M],tot=,from[M];
  10. int cost[M],cap[M],pre[N];
  11. int dis[N],ans[][];
  12. bool v[N];
  13. queue<int>q;
  14. void add(int u,int v,int w,int val)
  15. {
  16. to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; cap[tot]=w; cost[tot]=val; from[tot]=u;
  17. to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; cap[tot]=; cost[tot]=-val; from[tot]=v;
  18. }
  19. bool spfa()
  20. {
  21. memset(dis,,sizeof(dis));
  22. memset(v,,sizeof(v));
  23. dis[src]=; q.push(src); v[src]=true;
  24. int now;
  25. while(!q.empty())
  26. {
  27. now=q.front();
  28. q.pop(); v[now]=false;
  29. for(int i=front[now];i;i=nxt[i])
  30. {
  31. if(cap[i]>&&dis[to[i]]>dis[now]+cost[i])
  32. {
  33. dis[to[i]]=dis[now]+cost[i];
  34. pre[to[i]]=i;
  35. if(!v[to[i]])
  36. {
  37. v[to[i]]=true;
  38. q.push(to[i]);
  39. }
  40. }
  41. }
  42. }
  43. return dis[decc]<2e9;
  44. }
  45. int main()
  46. {
  47. int n,x;
  48. scanf("%d",&n);
  49. cnt=n+;decc=n+;
  50. for(int i=;i<=n;i++)
  51. for(int j=;j<=n;j++)
  52. {
  53. scanf("%d",&x);
  54. if(j>=i) continue;
  55. if(!x)
  56. {
  57. win[j]++;
  58. ans[j][i]=;
  59. cnt++;
  60. add(src,cnt,,);
  61. add(cnt,j,,);
  62. }
  63. else if(x==)
  64. {
  65. win[i]++;
  66. ans[i][j]=;
  67. cnt++;
  68. add(src,cnt,,);
  69. add(cnt,i,,);
  70. }
  71. else
  72. {
  73. cnt++;
  74. add(src,cnt,,);
  75. add(cnt,i,,);
  76. add(cnt,j,,);
  77. }
  78. }
  79. for(int i=;i<=n;i++)
  80. {
  81. for(int j=;j<=win[i];j++) add(i,decc,,);
  82. for(int j=win[i]+;j<n;j++) add(i,decc,,j-);
  83. }
  84. int tmp=;
  85. while(spfa())
  86. {
  87. tmp+=dis[decc];
  88. for(int i=pre[decc];i;i=pre[from[i]])
  89. {
  90. cap[i]--; cap[i^]++;
  91. }
  92. }
  93. for(int i=front[src];i;i=nxt[i])
  94. {
  95. int j1=front[to[i]],j2=nxt[j1];
  96. if(cap[j1]) ans[to[j2]][to[j1]]=;
  97. else ans[to[j1]][to[j2]]=;
  98. }
  99. int sum=n*(n-)*(n-)/;
  100. for(int i=;i<=n;i++)
  101. sum-=win[i]*(win[i]-)/;
  102. printf("%d\n",sum-tmp);
  103. for(int i=;i<=n;i++)
  104. {
  105. for(int j=;j<n;j++)
  106. printf("%d ",ans[i][j]);
  107. printf("\n");
  108. }
  109. }

错误:一边spfa一边更新答案

原因:费用流也有退流

[Wc2007]剪刀石头布的更多相关文章

  1. 2597: [Wc2007]剪刀石头布

    2597: [Wc2007]剪刀石头布 链接 分析: 费用流. 首先转化一下问题,整张图最优的情况是存在$C_n^3$个,即任意3个都行,然后考虑去掉最少不满足的三元环. 如果u赢了v,u向v连一条边 ...

  2. [Wc2007]剪刀石头布[补集转化+拆边]

    2597: [Wc2007]剪刀石头布 Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1157  Solved:  ...

  3. 【BZOJ2597】[Wc2007]剪刀石头布 最小费用流

    [BZOJ2597][Wc2007]剪刀石头布 Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之 ...

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

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

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

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

  6. bzoj2597: [Wc2007]剪刀石头布

    Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道 ...

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

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

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

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

  9. 【bzoj2597】[Wc2007]剪刀石头布 动态加边费用流

    题目描述 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道于统计有多少这 ...

随机推荐

  1. 20172305 2018-2019-1 《Java软件结构与数据结构》第六周学习总结

    20172305 2018-2019-1 <Java软件结构与数据结构>第六周学习总结 教材学习内容总结 本周内容主要为书第十章内容: 树(一种非线性结构,其中的元素被组织成一个层次结构) ...

  2. 《我是IT小小鸟》阅读心得

    虽然读这本书是老师布置的作业,但是读了几页后就被书中的内容所吸引住了.或许是因为我也是学这个专业的,所以书中的一些内容让我觉得非常的有兴趣.作为一个学习软件工程的大一学生还没真正的认识到这个专业的深奥 ...

  3. DB2的编目

    D在DB2数据库中,编目(catalog)这个单词很难理解,我自己当初在学习DB2的时候也常常被这个编目搞的很不明白,直到现在我个人也感觉到DB2中编目(catalog)这个术语用的不是很好,具体来说 ...

  4. so加载报错:dlopen failed: couldn't map ... Permission denied

    转自:https://blog.csdn.net/u013270444/article/details/60869376 问题描述: 我的应用当中集成了一个安全相关的sdk,而这个sdk中使用的so是 ...

  5. linux mysql表名大小写

    1.用ROOT登录,修改/etc/my.cnf 2.在[mysqld]下加入一行:lower_case_table_names=1 0:区分大小写,1:不区分大小写 3.重新启动数据库即可

  6. oracle 数据库 命令

    SQL PLUS 命令: SELECT * FROM ALL_TABLES;系统里有权限的表SELECT * FROM DBA_TABLES; 系统表SELECT * FROM USER_TABLES ...

  7. SQL Inserted和deleted详解

    create trigger updateDeleteTime on user for update as begin update user set UpdateTime=(getdate()) f ...

  8. lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现

    ReentrantLock的实现是基于其内部类FairSync(公平锁)和NonFairSync(非公平锁)实现的. 其可重入性是基于Thread.currentThread()实现的: 如果当前线程 ...

  9. 小程序 setData() 方法

    setData() 参数格式 字段 类型 必填 描述 最低版本 data Object 是 这次要改变的数据   callback Function 否 回调函数 1.5.0 callback 是一个 ...

  10. iOS开发--字典(NSDictionary)和JSON字符串(NSString)之间互转

    iOS开发--字典(NSDictionary)和JSON字符串(NSString)之间互转 1. 字典转Json字符串 // 字典转json字符串方法 -(NSString *)convertToJs ...