WC 2007 剪刀石头布

看到这个三元环的问题很容易可以考虑到求不合法的三元环的数量的最小值。

什么情况不合法?既然不合法,当且仅当三元环中有一个人赢了另外两个人。所以我们考虑对于一个人而言,如果她新增加了一场胜利,并且之前赢了 $ k $ 场,那么她的非剪刀石头布的胜利次数会增加 $ k $ 个。并且这样统计每个不合法情况正好只会被统计一遍。

这里就学到了一个非常厉害的建图方法,我们从每个人到 $ t $ 连很多条边,容量都是 1 ,费用设置为 $ 0,1,2,3,\dots $ 。然后从比赛向胜利者建立一条容量为 1 费用为 0 的边,从不确定的比赛向两方都建容量为 1 费用为 0 的边。

这样建图结束后,跑最小费用最大流就好了。

开始写的单路增广狂T。。。

#include "iostream"
#include "algorithm"
#include "cstring"
#include "cstdio"
#include "queue"
using namespace std;
#define MAXN 1006 class mincmaxf {
#define maxn 60003
public:
#define N 10006
#define M 100006
#define INF 0x3f3f3f3f
int tot, lnk[N], cur[N], ter[M], nxt[M], cap[M], cost[M], dis[N], ret;
bool vis[N];
void init( ) { tot = 1; }
int add(int u, int v, int w, int c) {
ter[++tot] = v, nxt[tot] = lnk[u], lnk[u] = tot, cap[tot] = w, cost[tot] = c;
return tot;
}
int Ade(int u, int v, int w, int c) { add(v, u, 0, -c); return add(u, v, w, c); }
bool spfa(int s, int t) {
memset(dis, 0x3f, sizeof(dis));
memcpy(cur, lnk, sizeof(lnk));
std::queue<int> q;
q.push(s), dis[s] = 0, vis[s] = 1;
while (!q.empty()) {
int u = q.front();
q.pop(), vis[u] = 0;
for (int i = lnk[u]; i; i = nxt[i]) {
int v = ter[i];
if (cap[i] && dis[v] > dis[u] + cost[i]) {
dis[v] = dis[u] + cost[i];
if (!vis[v]) q.push(v), vis[v] = 1;
}
}
}
return dis[t] != INF;
}
int dfs(int u, int t, int flow) {
if (u == t) return flow;
vis[u] = 1;
int ans = 0;
for (int &i = cur[u]; i && ans < flow; i = nxt[i]) {
int v = ter[i];
if (!vis[v] && cap[i] && dis[v] == dis[u] + cost[i]) {
int x = dfs(v, t, std::min(cap[i], flow - ans));
if (x) ret += x * cost[i], cap[i] -= x, cap[i ^ 1] += x, ans += x;
}
}
vis[u] = 0;
return ans;
}
int mcmf(int s, int t) {
int ans = 0;
while (spfa(s, t)) {
int x;
while ((x = dfs(s, t, INF))) ans += x;
}
return ret;
}
} F ;
int n;
int A[MAXN][MAXN] , re[MAXN][MAXN][2];
int s = 10002 , t = 10003;
int kk[MAXN][MAXN] , cnt;
inline int id( int x , int y ) { return !kk[x][y] ? (kk[x][y] = ++ cnt) : kk[x][y]; }
int r[MAXN];
int main() {
// freopen("6.in","r",stdin);
cin >> n;
cnt = n;
F.init();
for( int i = 1 ; i <= n ; ++ i )
for( int j = 1 ; j <= n ; ++ j ) {
scanf("%d",&A[i][j]);
if( A[i][j] ) F.Ade( s , id( i , j ) , 1 , 0 );
if( A[i][j] == 2 ) {
if( i < j )
re[i][j][0] = F.Ade(id(i, j), i, 1, 0), re[i][j][1] = F.Ade(id(i, j), j, 1, 0);
} else if( A[i][j] )
F.Ade( id( i , j ) , i , 1 , 0 );
else ++ r[i];
}
for( int i = 1 ; i <= n ; ++ i ) {
for( int j = 0 ; j < n - r[i] ; ++ j )
F.Ade( i , t , 1 , j );
}
cout << ( n * ( n - 1 ) / 2 * ( n - 2 ) / 3 ) - F.mcmf( s , t ) << endl;
for( int i = 1 ; i <= n ; ++ i ) {
for (int j = 1; j <= n; ++j) {
if (A[i][j] != 2) { printf("%d ",A[i][j]); }
else {
int ki = i , kj = j;
if( i > j ) swap( ki , kj );
if( F.cap[re[ki][kj][0]] ) printf("%d ",i>j);
else printf("%d ",i<j);
}
}
puts("");
}
}

WC 2007 剪刀石头布的更多相关文章

  1. 「WC 2007」剪刀石头布

    题目链接 戳我 \(Solution\) 直接求很明显不太好求,于是考虑不构成剪刀石头布的情况. 我们现在假设一个人\(i\)赢了\(x\)场,那么就会有\(\frac{x*(x-1)}{2}\) 我 ...

  2. 解题:WC 2007 石头剪刀布

    题面 要我们把边定向,最大化留下来的三元环数目......并不能直接做,考虑容斥,去掉不合法的数目. 那么三个点不成环当且仅当有一个点出度为2一个点入度为2,发现最终答案就是$C_n^3-\sum C ...

  3. poi读取excel模板,填充内容并导出,支持导出2007支持公式自动计算

    /** * 版权所有(C) 2016 * @author www.xiongge.club * @date 2016-12-7 上午10:03:29 */ package xlsx; /** * @C ...

  4. BZOJ 2007: [Noi2010]海拔

    2007: [Noi2010]海拔 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2410  Solved: 1142[Submit][Status] ...

  5. 【BZOJ-2597】剪刀石头布 最小费用最大流

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

  6. 开源WinForms界面开发框架Management Studio 选项卡文档 插件 Office 2007蓝色风格 后台线程

    Management Studio是我在WinForms小项目开发过程中搭建起来的一个插件式结构的应用程序框架,因为简单灵活又容易扩展,现在将它开源供读者参考. 跑起来的效果图如下所示,具备选项卡式多 ...

  7. 使用 python 实现 wc 命令程序的基本功能

    这里使用了 python 的基本代码实现了 Linux 系统下 wc 命令程序的基本功能. #!/usr/bin/env python #encoding: utf-8 # Author: liwei ...

  8. win7下wndows virtual pc 2007 装xp比新版本的 Windows virtual pc 好用

    2007下装xp虚拟机启动快,支持拖放.

  9. [SharePoint 2007/2010]Query SharePoint Calendar Event

    首先要搞清楚日历事件的各种类型,参考文章: http://sharepoint.microsoft.com/blog/Pages/BlogPost.aspx?PageType=4&ListId ...

随机推荐

  1. dubbo注册中心占位符无法解析问题(二)

    dubbo注册中心占位符无法解析问题 前面分析了dubbo注册中心占位符无法解析的问题. 并给出了2种解决办法: 降低mybatis-spring的版本至2.0.1及以下 自定义MapperScann ...

  2. 原生js-返回顶部

    html部分: <body style="height:2000px"> <div id="div1"> 返回顶部 </div&g ...

  3. Beta Scrum Meeting汇总

    第0次Alpha Scrum Meeting 第1次Alpha Scrum Meeting 第2次Alpha Scrum Meeting 第3次Alpha Scrum Meeting 第4次Alpha ...

  4. 【二食堂】Alpha - Scrum Meeting 10

    Scrum Meeting 10 例会时间:4.20 18:00~18:20 进度情况 组员 昨日进度 今日任务 李健 1. 与柴博合作完成登录注册页面issue 继续完成登录注册页面issue 柴博 ...

  5. FastAPI 学习之路(三十四)数据库多表操作

    之前我们分享的是基于单个的数据库表的操作,我们在设计数据库的时候也设计了跨表,我们可以看下数据库的设计. class User(Base): __tablename__ = "users&q ...

  6. windows下安装dirmap详细教程

    今天安装一下dirmap,纯小白非常详细的安装过程 1.先去下载dirmap 下载地址:https://github.com/H4ckForJob/dirmap 点这个绿色的code,然后再点下面这个 ...

  7. redhat 7.x 的防火墙软件firewall 介绍

    zone 的概念.firewall 一般有9个zone ,配置文件都在 /usr/lib/firewalld/zones/ 里面. 系统的配置文件目录就在 /usr/lib/firewalld 这个目 ...

  8. 策略路由——使用Router-Policy策略路由进行路由协议的引入

    1.实验目的:实现R3-R2-R1为访问主线路,R3-R4-R1为访问备份线路 2.实验拓扑及IP,如图; 3.基本配置(端口IP) R1: <Huawei>sys[Huawei]sys ...

  9. namespace之cgroup

    Linux Namespace,但是Namespace解决的问题主要是环境隔离的问题,这只是虚拟化中最最基础的一步,我们还需要解决对计算机资源使用上的隔离.也就是说,虽然你通过Namespace把我J ...

  10. 一维前缀和 连续数组和为k

    给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数. 滑动窗口没办法解决有负数的情况 方法一: 预处理 前缀和 sum_ij = preSum[j] - preSum[i-1 ...