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 ...
随机推荐
- Python--基础之socket编程
一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 美好的愿望: 最常用的软件服务器是 Web 服务器.一台机器里放一些网页或 Web 应用程序 ...
- PHP dir() 函数
使用 dir() 函数: <?php$d = dir(getcwd()); echo "Handle: " . $d->handle . "<br> ...
- hdu1166 敌兵布阵 (线段树单点更新)
Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营 地,Derek和Tidy的任务就是要监视这 ...
- VS2013 MFC基于对话框编程
前言一直利用Qt库做Ui设计,但针对于一些MFC项目,掌握一些必要的MFC开发技巧还是很有必要的.这篇博客里就将自己所学的一些MFC浅显知识记录一下,方便今后的学习.博客里只记录关键步骤. 一.新建M ...
- iframe中涉及父子页面跨域问题
什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制.所谓同源是指相同的域名.协议和端口,只要其中一项不同就为跨域. 举几个例子: http:/ ...
- mysql里面如何用sql语句让字符串转换为数字
sql语句将字符串转换为数字默认去掉单引号中的空格,遇到空格作为字符串截止, SELECT '123 and 1=1' +0 结果为123 MySQL里面如何用sql语句让字符串的‘123’转换为数字 ...
- [CSP-S模拟测试]:玄学题/c(数学)
题目传送门(内部题40) 输入格式 第一行:两个正整数$n$.$m$. 输出格式 第一行:一个整数,代表式子的值. 样例 样例输入1: 4 5 样例输出1: 0样例输入2: 799 8278 样例输出 ...
- (转)使用OpenGL ES显示图像
编写:jdneo - 原文:http://developer.android.com/training/graphics/opengl/index.html 转:http://hukai.me/and ...
- linux kafka进程挂了 自动重启
使用crontab,定时监控 kafka进程,发现挂了后重启. shell脚本如下: #!/bin/sh source /etc/profile proc_dir="/data/kafka& ...
- MySQL高级学习笔记(七):MySql主从复制
文章目录 复制的基本原理 slave会从master读取binlog来进行数据同步 三步骤+原理图 复制的基本原则 复制的最大问题 一主一从常见配置 mysql版本一致且后台以服务运行(双方能够pin ...