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, ...
随机推荐
- July 2nd, Week 27th Saturday, 2016
The beauty of the journey is found in the scenery along the way. 旅行之美在于沿途所见的风景. I remember that ther ...
- CSS3–2.css3 响应式布局
1.响应式布局 响应式布局是现在很流行的一个设计理念,随着移动互联网的盛行,为解决如今各式各样的浏览器分辨率以及不同移动设备的显示效果,设计师提出了响应式布局的设计方案.所谓的响应式布局,就是一个网站 ...
- 数据库递归查询-CTE
1.公用表表达式(CTE)的定义 公用表达式的定义包含三部分: 公用表表达式的名字(在WITH之后) 所涉及的列名(可选) 一个SELECT语句(紧跟AS之后), 公用表表达式的好处之一是可以在接下来 ...
- MVC4 遇到问题总结
1.路径编写: 举例1.<img src="../Login/VailCode" width="108" height="40"&g ...
- 【openGL】关于画点
#include "stdafx.h" #include <GL/glut.h> #include <stdlib.h> #include <math ...
- Java Hour 64 JVM 最大内存设置
从这篇博文起,不再是流水式的学习记录了,稍微改进下风格. 运行时获得当前JVM 设置大小 首先,-Xmx100000000指定最大的内存分配. public static void main(Stri ...
- 验证备份前设置CONFIGURE CONTROLFILE AUTOBACKUP ON/OFF; 的区别
关于rman的,环境: oracle 10.2.0 rman nocatalog方式 1.首先设置 CONFIGURE CONTROLFILE AUTOBACKUP ON; 然后进行数据库全备份 RM ...
- thinkphp自动验证中的静态验证和动态验证和批量验证
1.静态定义 在模型类里面预先定义好该模型的自动验证规则,我们称为静态定义. 举例说明,我们在模型类里面定义了$_validate属性如下: class UserModel extends Model ...
- C结构体中数据的内存对齐问题
转自:http://www.cnblogs.com/qwcbeyond/archive/2012/05/08/2490897.html 32位机一般默认4字节对齐(32位机机器字长4字节),64位机一 ...
- WebView相关
Android WebView使用基础 Android WebView中的JavaScript代码使用 很不错的例子:android webview js交互 第一节 (java和js交互)