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 ...
随机推荐
- Golang通脉之包的管理
在工程化的开发项目中,Go语言的源码复用是建立在包(package)基础之上的. 包(package)是多个Go源码的集合,是一种高级的代码复用方案,Go语言提供了很多内置包,如fmt.os.io等. ...
- csp-j 复赛感想
作者:博客园小蔡编程 这次是作者第一次参加csp-j的比赛 内心还是挺激动的 今天,作者就来和大家讨论一下这次csp-j的学习心得和感想 T1 分糖果 这题描述看似复杂 其实就是一道求最大取模的题 L ...
- [Git系列] Git 基本概念
版本控制系统 版本控制系统是一种帮助软件开发者实现团队合作和历史版本维护的软件,一个版本控制系统应具备以下列出的这几个基本功能: 允许开发者并发工作: 不允许一个开发者覆写另一个开发者的修改: 保存所 ...
- Java:HashTable类小记
Java:HashTable类小记 对 Java 中的 HashTable类,做一个微不足道的小小小小记 概述 public class Hashtable<K,V> extends Di ...
- Java:常用的容器小记
Java:常用的容器小记 对 Java 中的 常用容器,做一个微不足道的小小小小记 容器类概述 常见容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 M ...
- CF #749
A 题意 有个长度为n的序列, 每个数互不相同, 求总和最大的最长子序列, 并输出每个i: 题解 emmmmmm, 刚开始看到这个数据和题解被迷惑了, 以为有什么顺序, 并且一直在想一些复杂度较高的算 ...
- tcp 三次握手建立连接难点总结
所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包. 三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号 ...
- Flink 实践教程 - 入门(4):读取 MySQL 数据写入到 ES
作者:腾讯云流计算 Oceanus 团队 流计算 Oceanus 简介 流计算 Oceanus 是大数据产品生态体系的实时化分析利器,是基于 Apache Flink 构建的具备一站开发.无缝连接. ...
- elasticsearch7.x配置文件
前言: 以下配置文件基于elasticsearch-7.13.4版本,当然也适用于其它7.x版本 集群环境: 部署3个节点的集群,各个节点不做角色区分,既是master,也是data,在性能 上这种方 ...
- 组件通信之全局事件总线 & 消息订阅发布
全局事件总线 介绍 一种组件间通信的方式,适用于任意组件间通信. 在使用全局事件总线之前需要一些知识准备 所有组件实例的原型对象的原型对象就是 Vue 的原型对象,即VueComponent.prot ...