【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, ...
随机推荐
- WebService学习之旅(四)Apache Axis2的安装
一.Axis2简介 Axis2是目前使用较多的WebService引擎,它是Axis1.x的升级版本,不仅支持SOAP1.1和SOAP1.2,而且也提供了对REST风格WebService的支持. A ...
- linux下phpstudy的搭建以及网站的搭建
step1: 下载SSH连接到IP地址(阿里云上购买的) step2: 安装下载phpstudywget -c http://lamp.phpstudy.net/phpstudy.bin chmod ...
- python深浅拷贝问题
Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 一.对象赋值 又叫变量对对象的引用 l ...
- Linux下文件以及文件名编码转换
1.查看文件编码方式--file 文件名(但不是很准确) yang@mint-linux ~ $ file baidu.html baidu.html: HTML document, UTF-8 Un ...
- osx launchpad图标的删除
安装了个parallels desktop之后,OSX中的launchpad中的图标多了不少,可是好多都不是我自己想要的,我们该怎么删除或者修改呢,下面介绍一些方法: ①直接操作Appications ...
- poi导出word模板项目实例(一个文件)
在页面上填写值,然后导出到word模板中,并把页面上的值带到模板中,也就是导出word文档,提前有word 的模板形式, 1.jsp 页面 <table class="formTa ...
- flask模板语言
由于Django的模板引擎和Flask中的Jinja2模板引擎有很多一样的地方,所以我将一样的地方总结到了独立的文章中 https://www.cnblogs.com/kuxingseng95/art ...
- ios之UITextfield
//初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 13 ...
- 【数学 exgcd】bzoj1407: [Noi2002]Savage
exgcd解不定方程时候$abs()$不能乱加 Description Input 第1行为一个整数N(1<=N<=15),即野人的数目. 第2行到第N+1每行为三个整数Ci, Pi, L ...
- 初涉二维数点问题&&bzoj1935: [Shoi2007]Tree 园丁的烦恼
离线好评 Description 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草.有一天国王漫步在花园里,若有所思,他问一个 ...