WC 2007 剪刀石头布
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 剪刀石头布的更多相关文章
- 「WC 2007」剪刀石头布
题目链接 戳我 \(Solution\) 直接求很明显不太好求,于是考虑不构成剪刀石头布的情况. 我们现在假设一个人\(i\)赢了\(x\)场,那么就会有\(\frac{x*(x-1)}{2}\) 我 ...
- 解题:WC 2007 石头剪刀布
题面 要我们把边定向,最大化留下来的三元环数目......并不能直接做,考虑容斥,去掉不合法的数目. 那么三个点不成环当且仅当有一个点出度为2一个点入度为2,发现最终答案就是$C_n^3-\sum C ...
- poi读取excel模板,填充内容并导出,支持导出2007支持公式自动计算
/** * 版权所有(C) 2016 * @author www.xiongge.club * @date 2016-12-7 上午10:03:29 */ package xlsx; /** * @C ...
- BZOJ 2007: [Noi2010]海拔
2007: [Noi2010]海拔 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2410 Solved: 1142[Submit][Status] ...
- 【BZOJ-2597】剪刀石头布 最小费用最大流
2597: [Wc2007]剪刀石头布 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1016 Solved: ...
- 开源WinForms界面开发框架Management Studio 选项卡文档 插件 Office 2007蓝色风格 后台线程
Management Studio是我在WinForms小项目开发过程中搭建起来的一个插件式结构的应用程序框架,因为简单灵活又容易扩展,现在将它开源供读者参考. 跑起来的效果图如下所示,具备选项卡式多 ...
- 使用 python 实现 wc 命令程序的基本功能
这里使用了 python 的基本代码实现了 Linux 系统下 wc 命令程序的基本功能. #!/usr/bin/env python #encoding: utf-8 # Author: liwei ...
- win7下wndows virtual pc 2007 装xp比新版本的 Windows virtual pc 好用
2007下装xp虚拟机启动快,支持拖放.
- [SharePoint 2007/2010]Query SharePoint Calendar Event
首先要搞清楚日历事件的各种类型,参考文章: http://sharepoint.microsoft.com/blog/Pages/BlogPost.aspx?PageType=4&ListId ...
随机推荐
- 封装一个的toast弹出框(vue项目)
逆风的方向,更适合飞翔 实现效果 实现步骤 先写出一个toast组件 // Toast.vue <template> <div id="toast" :class ...
- [对对子队]发布声明Beta
Beta版本的新功能 新增的游戏内容 循环部分关卡 Beta阶段我们制作了游戏的第4-6关,为循环部分关卡.这一部分的关卡设计以编程的循环思想为基础,在流水线中加入了新的命令--循环语句,并以此为核心 ...
- 用cmd命令行创建vue项目模板
1.进入cmd命令行 输入存放项目的位置 2.通过vue create 项目名称 创建项目 3.选择Manually select features 4.通过空格选中第1.2.5.6.7.去掉8 4. ...
- Spring源码解读(一):Spring的背景起源及框架整体介绍
一.前言 Spring起源于2002年Rod Johnson写的一本书<Expert One-on-One J2EE>,书里介绍了Java企业应用程序开发情况,并指出Java EE和EJB ...
- 矩形覆盖 牛客网 剑指Offer
矩形覆盖 牛客网 剑指Offer 题目描述 我们可以用21的小矩形横着或者竖着去覆盖更大的矩形.请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? class Solution: ...
- 聊聊@Transactional 的失效场景,有哪些坑?
先别急着回答,看完再说也不迟嘛.我们都知道在 Spring 项目中,我们可以直接使用注解 @Transactional 来标识一个事务方法.然而,你可能并不知道这个事务是不是按照你想的方式执行.下面我 ...
- pycharm基本使用与破解
一.pycharm基本使用 pycharm这款ide软件虽然功能强大,但正因为他的强大,所以小白在刚使用这款软件时上手会有点难度,今天我们就来介绍一下ptcharm的基本使用. 1.基本配置 我们安装 ...
- vscode + vim 全键盘操作高效搭配方案
基础知识 vscode-vim vscode-vim是一款vim模拟器,它将vim的大部分功能都集成在了vscode中,你可以将它理解为一个嵌套在vscode中的vim. 由于该vim是被模拟的的非真 ...
- Mysql教程:(六)修改语句、、删除语句、字符查询like
1.修改语句 update 表名 set where 条件 mysql> update student set birth=1988,department='中文系' where id=901 ...
- mysql流程控制结构case when
一.case 使用场景 简单函数 CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement ...