【bzoj2597】[Wc2007]剪刀石头布 动态加边费用流
题目描述
输入
输出
样例输入
3
0 1 2
0 0 2
2 2 0
样例输出
1
0 1 0
0 0 1
1 0 0
题解
动态加边费用流
首先正着想很难想,考虑反过来:已知最多可能产生的情况个数为$C_n^3$,求最少破坏多少个“剪刀石头布”情况?
然后考虑:对于任意的一个点(一只队伍),如果它有某两条出边,那么就破坏了这三个点之间的“剪刀石头布”情况。
而如果某个点的出度为d,则任意选出两条边的方案数为$C_d^2=\frac{d(d-1)}2$,差分得$C_d^2-C_{d-1}^2=d-1$。
于是我们可以使用使用拆边法来解决问题:S->每条边,容量为1,费用为0;每条边如果是有向边,则向指向发出边的点(赢的队伍),否则指向两个点,容量为1,费用为0。对于每个点,拆出n条边连向T,第i条边的容量为i-1。
然后跑最小费用流出解。由于直接跑会TLE,所以使用动态加边来优化。
最后满流的边指向的队伍就是赢的队伍。
#include <cstdio>
#include <cstring>
#include <queue>
#define N 11000
#define M 2200000
#define pos(i , j) (i - 1) * n + j
using namespace std;
queue<int> q;
int head[N] , to[M] , val[M] , cost[M] , next[M] , cnt = 1 , s , t , dis[N] , from[N] , pre[N] , ans[110][110];
void add(int x , int y, int v , int c)
{
to[++cnt] = y , val[cnt] = v , cost[cnt] = c , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = 0 , cost[cnt] = -c , next[cnt] = head[y] , head[y] = cnt;
}
bool spfa()
{
int x , i;
memset(from , -1 , sizeof(from));
memset(dis , 0x3f , sizeof(dis));
dis[s] = 0 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
if(val[i] && dis[to[i]] > dis[x] + cost[i])
dis[to[i]] = dis[x] + cost[i] , from[to[i]] = x , pre[to[i]] = i , q.push(to[i]);
}
return ~from[t];
}
int calc(int x)
{
int i;
for(i = head[x] ; i ; i = next[i])
if(!val[i])
return to[i];
return 0;
}
int mincost()
{
int ans = 0 , i , k;
while(spfa())
{
k = 1 << 30;
for(i = t ; i != s ; i = from[i]) k = min(k , val[pre[i]]);
ans += k * dis[t] , add(from[t] , t , 1 , cost[pre[t]] + 1);
for(i = t ; i != s ; i = from[i]) val[pre[i]] -= k , val[pre[i] ^ 1] += k;
}
return ans;
}
int main()
{
int n , i , j , x;
scanf("%d" , &n) , s = 0 , t = n * n + n + 1;
for(i = 1 ; i <= n ; i ++ )
{
for(j = 1 ; j <= n ; j ++ )
{
scanf("%d" , &x);
if(i < j)
{
add(s , pos(i , j) , 1 , 0);
if(x != 0) add(pos(i , j) , n * n + i , 1 , 0);
if(x != 1) add(pos(i , j) , n * n + j , 1 , 0);
}
}
}
for(i = 1 ; i <= n ; i ++ )
add(n * n + i , t , 1 , 0);
printf("%d\n" , n * (n - 1) * (n - 2) / 6 - mincost());
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
if(i < j)
x = calc(pos(i , j)) - n * n , ans[x][i + j - x] = 1;
for(i = 1 ; i <= n ; i ++ )
{
for(j = 1 ; j <= n ; j ++ ) printf("%d " , ans[i][j]);
printf("\n");
}
return 0;
}
【bzoj2597】[Wc2007]剪刀石头布 动态加边费用流的更多相关文章
- bzoj2879(动态加边费用流)
参考题解:http://blog.csdn.net/yxuanwkeith/article/details/52254602 //开始跑费用流用的dijkstra,一直错,后来发现动态加边后我不会处理 ...
- [bzoj2597][Wc2007]剪刀石头布_费用流
[Wc2007]剪刀石头布 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 题解: 发现直接求三元环不好求,我们考虑任选三个点不是 ...
- BZOJ2597 [Wc2007]剪刀石头布 【费用流】
题目链接 BZOJ2597 题解 orz思维差 既然是一张竞赛图,我们选出任意三个点都可能成环 总方案数为 \[{n \choose 3}\] 如果三个点不成环,会发现它们的度数是确定的,入度分别为\ ...
- bzoj2597: [Wc2007]剪刀石头布(费用流)
传送门 不得不说这思路真是太妙了 考虑能构成三元组很难,那我们考虑不能构成三元组的情况是怎么样 就是说一个三元组$(a,b,c)$,其中$a$赢两场,$b$赢一场,$c$没有赢 所以如果第$i$个人赢 ...
- BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)
题目大概是说n个人两两进行比赛,问如何安排几场比赛的输赢使得A胜B,B胜C,C胜A这种剪刀石头布的三元组最多. 这题好神. 首先,三元组总共有$C_n^3$个 然后考虑最小化不满足剪刀石头布条件的三元 ...
- BZOJ2597 WC2007剪刀石头布(费用流)
考虑使非剪刀石头布情况尽量少.设第i个人赢了xi场,那么以i作为赢家的非剪刀石头布情况就为xi(xi-1)/2种.那么使Σxi(xi-1)/2尽量小即可. 考虑网络流.将比赛建成一排点,人建成一排点, ...
- bzoj2597: [Wc2007]剪刀石头布
Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道 ...
- 【bzoj2879】[Noi2012]美食节 费用流+动态加边
原文地址:http://www.cnblogs.com/GXZlegend 题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他 ...
- Codeforces 708D 上下界费用流
给你一个网络流的图 图中可能会有流量不平衡和流量>容量的情况存在 每调整一单位的流量/容量 需要一个单位的花费 问最少需要多少花费使得原图调整为正确(可行)的网络流 设当前边信息为(u,v,f, ...
随机推荐
- codevs 1097 校门外的树 2005年NOIP全国联赛普及组 (线段树)
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可 ...
- iOS上架问题解决
dns问题 http://iphone.91.com/tutorial/syjc/140509/21686339.html 网络问题 手机4g开wifi,上传提交多次 时间问题 东八区下午6点上架成功 ...
- javascript基本类型和引用类型,作用域和内存问题
基本类型(null.undefined.boolean.number.string)和引用类型(Object 对象) 1 基本类型:只能不存一个值,一种类型:从一个变量向另一个变量复制基本类型的值, ...
- Block中__block实现原理
三.Block中__block实现原理 我们继续研究一下__block实现原理. 1.普通非对象的变量 先来看看普通变量的情况. #import <Foundation/Foundation.h ...
- 【工具篇】在.Net中实现HTML生成图片或PDF的几种方式
前段时间由于项目上的需求,要在.Net平台下实现把HTML内容生成图片或PDF文件的功能,特意在网上研究了几种方案,这里记录一下以备日后再次使用.当时想着找一种开发部署都比较清爽并且运行稳定的方案,但 ...
- struct结构体内存大小
一. 基本原则 1. struct中成员变量的声明顺序,与成员变量对应的内存顺序是一致的: 2. struct本身的起始存储地址必须是成员变量中最长的数据类型的整倍数,注意是最长的数据类型,而不是最长 ...
- 用border实现三角形的过程
div{ width:100px; height:100px; background:yellow; border-top: 20px solid red; border-right:20px sol ...
- Paxos算法与Zookeeper分析,zab (zk)raft协议(etcd) 8. 与Galera及MySQL Group replication的比较
mit 分布式论文集 https://github.com/feixiao/Distributed-Systems wiki上描述的几种都明白了就出师了 raft 和 zab 是类似的,都是1.先选举 ...
- XML解析(一) DOM解析
XML解析技术主要有三种: (1)DOM(Document Object Model)文档对象模型:是 W3C 组织推荐的解析XML 的一种方式,即官方的XML解析技术. (2)SAX(Simple ...
- javascript设计模式(张容铭)学习笔记 - 照猫画虎-模板方法模式
模板方法模式(Template Method):父类中定义一组操作算法骨架,而降一些实现步骤延迟到子类中,使得子类可以不改变父类的算法结构的同时可重新定义算法中某些实现步骤. 项目经理体验了各个页面的 ...