BZOJ 2597: [Wc2007]剪刀石头布(费用流)
解题思路
考虑全集-不能构成三元环的个数。如果三个点不能构成三元环,一定有一个点的入度为\(2\),继续扩展,如果一个点的度数为\(3\),则会失去3个三元环。对于一个点来说,它所产生的不能构成三元环的贡献为\(C (deg[x],2)\),而度数每增加\(1\),对于答案的影响就是\(C(deg[x]+1,2)-C(deg[x],2)=deg[x]\),然后就可以建图了。考虑把边当做点,对于一条未确定的边来说,它只能对两个节点中的一个产生\(1\)个度数的贡献,所以让每个边向点连流量为1,费用为0的边。然后让源点向每条未确定的边连流量为1,费用为0的边。再让每个点向汇点连流量为\(1\),费用为\(deg[x],deg[x]+1,deg[x]+2,...n\)的边。跑一遍费用流。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
const int MAXN = 100005;
const int MAXM = 500005;
const int inf = 0x3f3f3f3f;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
}
int n,head[MAXN],cnt=1,to[MAXM<<1],nxt[MAXM<<1],val[MAXM<<1],cost[MAXM<<1];
int deg[MAXN],num,S,T,op[105][105],dis[MAXN],incf[MAXN],pre[MAXN],ans,tmp[105][105];
bool vis[MAXN];
queue<int> Q;
inline void add(int bg,int ed,int w,int z){
to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,cost[cnt]=z,head[bg]=cnt;
}
bool spfa(){
while(Q.size()) Q.pop();
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
Q.push(S);vis[S]=1;incf[S]=inf;dis[S]=0;
while(Q.size()){
int x=Q.front();Q.pop();vis[x]=0;
for(int i=head[x];i;i=nxt[i]){
int u=to[i];
if(dis[x]+cost[i]<dis[u] && val[i]){
dis[u]=dis[x]+cost[i];
incf[u]=min(incf[x],val[i]);
pre[u]=i;
if(!vis[u]) vis[u]=1,Q.push(u);
}
}
}
return (dis[T]==inf)?0:1;
}
inline void update(){
int x=T,i;
while(x!=S){
i=pre[x];
val[i]-=incf[T];
val[i^1]+=incf[T];
x=to[i^1];
}
ans-=incf[T]*dis[T];
}
int main(){
n=rd();int x;T=n+2;S=n+1;num=T;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
x=rd();op[i][j]=x;
if(x==1) deg[i]++;
}
for(int i=1;i<=n;i++) if(deg[i]>1) ans-=deg[i]*(deg[i]-1)/2;
for(int i=1;i<=n;i++)
for(int j=deg[i];j<=n;j++)
add(i,T,1,j),add(T,i,0,-j);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(op[i][j]==2){
num++;add(S,num,1,0);add(num,S,0,0);
add(num,i,1,0),add(i,num,0,0);
add(num,j,1,0),add(j,num,0,0);
tmp[i][j]=tmp[j][i]=num;
}
while(spfa()) update();
ans+=n*(n-1)*(n-2)/6;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(op[i][j]==2){
for(int k=head[tmp[i][j]];k;k=nxt[k]){
if(to[k]==S) continue;
if(!val[k]) {
if(to[k]==i) op[i][j]=1,op[j][i]=0;
else op[j][i]=1,op[i][j]=0;
}
}
}
printf("%d\n",ans);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
printf("%d ",op[i][j]);
putchar('\n');
}
return 0;
}
BZOJ 2597: [Wc2007]剪刀石头布(费用流)的更多相关文章
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...
- bzoj 2597 [Wc2007]剪刀石头布——费用流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 三个人之间的关系,除了“剪刀石头布”,就是有一个人赢了2局:所以考虑算补集,则每个人对 ...
- bzoj 2597: [Wc2007]剪刀石头布【最小费用最大流】
脑子不太清楚一个zz问题调了好久-- 首先正难则反,因为三元环好像没什么特点,就考虑让非三元环个数最小 考虑非三元环特点,就是环上一定有一个点的入度为2,联系整张图,三元环个数就是每个点C(入度,2) ...
- [WC2007]剪刀石头布——费用流
比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...
- 2597: [Wc2007]剪刀石头布
2597: [Wc2007]剪刀石头布 链接 分析: 费用流. 首先转化一下问题,整张图最优的情况是存在$C_n^3$个,即任意3个都行,然后考虑去掉最少不满足的三元环. 如果u赢了v,u向v连一条边 ...
- [bzoj 1449] 球队收益(费用流)
[bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
- Luogu4249 WC2007 石头剪刀布 费用流
传送门 考虑竞赛图三元环计数,设第\(i\)个点的入度为\(d_i\),根据容斥,答案为\(C_n^3 - \sum C_{d_i}^2\) 所以我们需要最小化\(\sum C_{d_i}^2\) 考 ...
- BZOJ 3171 循环格(费用流)
题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...
随机推荐
- sql 实现分页+分组并取出分组内的前n条数据
一.建表 if exists (select * from sysobjects where id = OBJECT_ID('[test]') and OBJECTPROPERTY(id, 'IsUs ...
- GPIO软件模拟IIC时序
一.MPU6050中的IIC时序 1.1 START和STOP SDA和SCL在高电平时,SDA拉低表示START.SCL拉低,表示可以传输数据. SDA和SCL在低电平时,SDA拉高表示STOP. ...
- BZOJ 3585: mex(分块+莫队)
传送门 解题思路 首先直接莫队是能被卡的,时间复杂度不对.就考虑按照值域先进行分块再进行莫队,然后统计答案的时候就暴力扫所有的块,直到一个块内元素不满,再暴力扫这个块就行了,时间复杂度O(msqrt( ...
- 【c#技术】一篇文章搞掂:水晶报表
更新数据源 应该先从[数据库]——[数据库专家]——[刷新]——[数据库]——[验证数据库] 必须先刷新,不然验证数据库无效 XP下,打开水晶报表提示无法创建目录或文件,删除临时目录Temp中文件即可 ...
- *.tar 用 tar –xvf 解压 *.gz 用 gzip -d或者gunzip 解压 *.tar.gz和*.tgz 用 tar –xzf 解压 *.bz2 用 bzip2 -d或者用bunzip2 解压 、*.tar.bz2用tar –xjf 解压
解压: 1.*.tar 用 tar –xvf 解压, --skip-old-files跳过已经存在的文件,压缩用tar -cvf 2.*.bz2 用 bzip2 -d或者用bunzip2 解压 3.* ...
- php打包下载文件
使用前请先开启:查看下php.ini里面的extension=php_zip.dll前面的分号有没有去掉; $zip=new \ZipArchive(); $zifile = 'download/' ...
- Mamen所需要的jar包怎么生成
Mamen所需要的jar包怎么生成 使用 mamen 难免碰到,不知道的 jar 包,不知道怎么在 pom 文件中写,分享一个网址,可以把你想要的 jar 包生成 pom 配置文件,个人感觉非常好用. ...
- Dubbo 系列(07-1)集群容错 - 服务字典
Dubbo 系列(07-1)集群容错 - 服务字典 [toc] Spring Cloud Alibaba 系列目录 - Dubbo 篇 1. 背景介绍 本篇文章,将开始分析 Dubbo 集群容错方面的 ...
- Zookeeper安装配置及简单使用
我使用的CentOS 7阿里云服务器,ZK依赖JDK,需要先安装jdk并配置jdk环境变量. 1.安装wget: yum –y install wget 2.下载Zookeeper(http://mi ...
- js函数方法
/** * call()和apply * 这两个方法都是函数对象的方法,需要通过函数对象来调用 * 当对函数调用call()和apply()都会调用函数执行 * 在调用call()和apply()可以 ...