BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)
题目大概是说n个人两两进行比赛,问如何安排几场比赛的输赢使得A胜B,B胜C,C胜A这种剪刀石头布的三元组最多。
这题好神。
- 首先,三元组总共有$C_n^3$个
- 然后考虑最小化不满足剪刀石头布条件的三元组个数,而要求的结果就是总数-这个不满足的个数了:
- 对于三个人构不成剪刀石头布现象,当且仅当,其中一个人赢了其他两个人
- 而由于这是完全图,如果一个人赢了$x_i$场那么包含这个人且这个人赢的次数最多的不满足剪刀石头布现象的三元组就有$C_{x_i}^2$个
- 所以目的就是最小化$\sum C_{x_i}^2$,即$\sum x_i^2-C_n^2$,其中$C_n^2$是常数可以拿开
- 考虑用最小费用最大流求解$\sum x_i^2$的最小值,源点-比赛-人-汇点这样连边:
- 源点到各个比赛的边是容量1费用0
- 比赛到人是容量1费用0的边
- 而人到汇点,根据那个目标式,可知如果流量是$f$,那么费用是$f^2$,解决的方式就是依次连接容量1费用分别是1、3、5、7、9……的边!
- 构图完毕跑最小费用最大流,最多的剪刀石头布现象数就是$C_n^3-(MCMF-C_n^2)$,最后再遍历一下残量网络输出方案即可
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 11111
#define MAXM 111111*4
struct Edge{
int u,v,cap,cost,next;
}edge[MAXM];
int vs,vt,NV,NE,head[MAXN];
void addEdge(int u,int v,int cap,int cost){
edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].u=v; edge[NE].v=u; edge[NE].cap=; edge[NE].cost=-cost;
edge[NE].next=head[v]; head[v]=NE++;
}
int d[MAXN],pre[MAXN];
bool vis[MAXN];
bool SPFA(){
for(int i=; i<NV; ++i){
d[i]=INF; vis[i]=;
}
d[vs]=; vis[vs]=;
queue<int> que;
que.push(vs);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap && d[v]>d[u]+edge[i].cost){
d[v]=d[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=;
que.push(v);
}
}
}
vis[u]=;
}
return d[vt]!=INF;
}
int MCMF(){
int res=;
while(SPFA()){
int flow=INF,cost=;
for(int u=vt; u!=vs; u=edge[pre[u]].u){
flow=min(flow,edge[pre[u]].cap);
}
for(int u=vt; u!=vs; u=edge[pre[u]].u){
edge[pre[u]].cap-=flow;
edge[pre[u]^].cap+=flow;
cost+=flow*edge[pre[u]].cost;
}
res+=cost;
}
return res;
}
int ans[][];
int main(){
int n,a;
scanf("%d",&n);
vs=n*n+n; vt=vs+; NV=vt+; NE=;
memset(head,-,sizeof(head));
for(int i=; i<n; ++i){
int cost=;
for(int j=; j<=n; ++j){
addEdge(n*n+i,vt,,cost);
cost+=;
}
}
for(int i=; i<n; ++i){
for(int j=; j<n; ++j){
scanf("%d",&a);
if(i>=j) continue;
addEdge(vs,i*n+j,,);
if(a==){
addEdge(i*n+j,n*n+i,,);
}else if(a==){
addEdge(i*n+j,n*n+j,,);
}else{
addEdge(i*n+j,n*n+i,,);
addEdge(i*n+j,n*n+j,,);
}
}
}
printf("%d\n",n*(n-)*(n-)/-(MCMF()-(n-)*n/)/);
for(int x=; x<n; ++x){
for(int y=x+; y<n; ++y){
for(int i=head[x*n+y]; i!=-; i=edge[i].next){
if(i& || edge[i].cap) continue;
if(edge[i].v==x+n*n){
ans[x][y]=; ans[y][x]=;
}else{
ans[x][y]=; ans[y][x]=;
}
}
}
}
for(int i=; i<n; ++i){
for(int j=; j<n; ++j) printf("%d ",ans[i][j]);
putchar('\n');
}
return ;
}
BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)的更多相关文章
- 【BZOJ-2597】剪刀石头布 最小费用最大流
2597: [Wc2007]剪刀石头布 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1016 Solved: ...
- bzoj2597: [Wc2007]剪刀石头布(费用流)
传送门 不得不说这思路真是太妙了 考虑能构成三元组很难,那我们考虑不能构成三元组的情况是怎么样 就是说一个三元组$(a,b,c)$,其中$a$赢两场,$b$赢一场,$c$没有赢 所以如果第$i$个人赢 ...
- [bzoj2597][Wc2007]剪刀石头布_费用流
[Wc2007]剪刀石头布 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 题解: 发现直接求三元环不好求,我们考虑任选三个点不是 ...
- BZOJ2597 WC2007剪刀石头布(费用流)
考虑使非剪刀石头布情况尽量少.设第i个人赢了xi场,那么以i作为赢家的非剪刀石头布情况就为xi(xi-1)/2种.那么使Σxi(xi-1)/2尽量小即可. 考虑网络流.将比赛建成一排点,人建成一排点, ...
- BZOJ2597 [Wc2007]剪刀石头布 【费用流】
题目链接 BZOJ2597 题解 orz思维差 既然是一张竞赛图,我们选出任意三个点都可能成环 总方案数为 \[{n \choose 3}\] 如果三个点不成环,会发现它们的度数是确定的,入度分别为\ ...
- [板子]最小费用最大流(Dijkstra增广)
最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...
- bzoj1927最小费用最大流
其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→ =_=你TM逗我 刚要删突然感觉dinic的模 ...
- ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)
将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...
- HDU5900 QSC and Master(区间DP + 最小费用最大流)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...
随机推荐
- 解决 The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
这个时候我们只需要flush privileges 一下就OK了,mysql> flush privileges;Query OK, 0 rows affected (0.01 sec)
- BigInteger类型的解析_超详细解析
/*9876543210987654234522345 214748364723453452323452345 2147483647234523452323452345 181760911432744 ...
- 常用iOS的第三方框架
图像:1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网络下载图片并进行缓存.可对图片进行缩放等 ...
- windows 下的tcping 小插件
如果把插件放在根目录 就要能过cmd切换到根目录 cd \ c:\>tcping -d -t -i 0.06 www.baidu.com 将文件放在c:\WINDOWS\system32目录下, ...
- mysql 查看用户的权限
show grants for 'username'@'%';
- Jcapta
http://blog.csdn.net/shadowsick/article/details/8575471
- 【JAVA与DOM4J实现对XML文档的CRUD操作】
一.简介 1.网上下载DOM4J 1.6.1压缩包,解压开之后,发现几个目录和一个jar文件,jar文件是必须的文件其它目录: docs目录:帮助文档的目录,单击index.html: Quick s ...
- float 的有效数字为七位是怎么得出来的
以下内容来自CSDN网友xian_wwq的回答(http://bbs.csdn.net/topics/390874239): float: 1bit(符号位) 8bits(指数位) 23bits( ...
- [Tools] 使用XP远程登录Win8系统
[背景] 完成最基本的设置后,发现xp依然不能远程访问win8桌面,搜索后发现需要进一步设置 [开工] 按照参考资料进行设置,下面的参考资料已经写的很详细了,只是参考资料2中的文件名: redss ...
- 字幕文件 WebVTT 与 srt 之间的互相转化
1. WebVTT 2 srt 1. 用记事本打开 .vtt 文件: 2. 在记事本中点击 编辑 -> 替换 -> 查找内容中输入".",替换为中输入",& ...