题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597

三个人之间的关系,除了“剪刀石头布”,就是有一个人赢了2局;所以考虑算补集,则每个人对答案的贡献是 \( -C_{f[ i ]}^{2} = \frac{f[ i ]*(f[ i ]-1)}{2}\) ,其中 f[ i ] 表示这个人赢的局数。

所以一个人多赢了一局,对答案的贡献是 -f[ i ] ;再多赢一局,就是 -( f[ i ] + 1 ) ……只要每个人向汇点连足够的边,其中每条边容量是1、费用依次为 f[ i ] , f[ i ]+1 , …… 就行了,因为会先走费用小的,符合意义。

对于每场未确定比赛,新建一个点,从源点向它连容量为1、费用为0的边;然后从它分别向两个人连容量为1、费用为0的边,表示这场比赛会令其中一个人增加费用。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=,M=,INF=M;
int n,cnt,f[N],c[N],ans,hd[N+M],xnt=,b[N][N],dy[M];
int dis[N+M],pre[N+M],incf[N+M];bool vis[N+M];
struct Ed{
int fr,to,nxt,cap,w;
Ed(int f=,int a=,int b=,int c=,int d=):fr(f),to(a),nxt(b),cap(c),w(d) {}
}ed[(N*N+M*)<<];
queue<int> q;
int Mn(int a,int b){return a<b?a:b;}
void add(int x,int y,int z,int w)
{
ed[++xnt]=Ed(x,y,hd[x],z,w);hd[x]=xnt;
ed[++xnt]=Ed(y,x,hd[y],,-w);hd[y]=xnt;
}
bool spfa()
{
memset(dis,0x3f,sizeof dis);
dis[]=;vis[]=;q.push();
pre[cnt]=;incf[]=INF;
while(q.size())
{
int k=q.front();q.pop();vis[k]=;
for(int i=hd[k],v;i;i=ed[i].nxt)
if(ed[i].cap&&dis[v=ed[i].to]>dis[k]+ed[i].w)
{
dis[v]=dis[k]+ed[i].w;pre[v]=i;
incf[v]=Mn(incf[k],ed[i].cap);
if(!vis[v])q.push(v),vis[v]=;
}
}
return pre[cnt];
}
void ek()
{
int ret=incf[cnt];
for(int k=pre[cnt];k;k=pre[ed[k].fr])
{
ed[k].cap-=ret;ed[k^].cap+=ret;
ans-=ed[k].w*ret;
}
}
int main()
{
scanf("%d",&n);cnt=n;int val=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
scanf("%d",&b[i][j]);if(i>=j)continue;
if(b[i][j]==)f[i]++; else if(!b[i][j])f[j]++;
else
{
c[i]++;c[j]++;cnt++;val++;
add(,cnt,,);add(cnt,i,,);add(cnt,j,,);
dy[cnt-n]=xnt-;
}
}
cnt++; ans=n*(n-)*(n-)/;
for(int i=;i<=n;i++)
{
ans-=f[i]*(f[i]-)/;
for(int j=;j<c[i];j++)add(i,cnt,,f[i]+j);
}
while(spfa())ek();
for(int i=,p=;i<=n;i++)
for(int j=;j<=n;j++)
{
if(i>=j||b[i][j]<)continue;
p++;
if(ed[dy[p]].cap)b[i][j]=,b[j][i]=;
else b[i][j]=,b[j][i]=;
}
printf("%d\n",ans);
for(int i=;i<=n;i++,puts(""))
for(int j=;j<=n;j++)printf("%d ",b[i][j]);
return ;
}

bzoj 2597 [Wc2007]剪刀石头布——费用流的更多相关文章

  1. BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)

    BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...

  2. BZOJ 2597: [Wc2007]剪刀石头布(费用流)

    传送门 解题思路 考虑全集-不能构成三元环的个数.如果三个点不能构成三元环,一定有一个点的入度为\(2\),继续扩展,如果一个点的度数为\(3\),则会失去3个三元环.对于一个点来说,它所产生的不能构 ...

  3. bzoj 2597: [Wc2007]剪刀石头布【最小费用最大流】

    脑子不太清楚一个zz问题调了好久-- 首先正难则反,因为三元环好像没什么特点,就考虑让非三元环个数最小 考虑非三元环特点,就是环上一定有一个点的入度为2,联系整张图,三元环个数就是每个点C(入度,2) ...

  4. [WC2007]剪刀石头布——费用流

    比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...

  5. 2597: [Wc2007]剪刀石头布

    2597: [Wc2007]剪刀石头布 链接 分析: 费用流. 首先转化一下问题,整张图最优的情况是存在$C_n^3$个,即任意3个都行,然后考虑去掉最少不满足的三元环. 如果u赢了v,u向v连一条边 ...

  6. [bzoj 1449] 球队收益(费用流)

    [bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...

  7. bzoj 1070: [SCOI2007]修车 费用流

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2785  Solved: 1110[Submit][Status] ...

  8. Luogu4249 WC2007 石头剪刀布 费用流

    传送门 考虑竞赛图三元环计数,设第\(i\)个点的入度为\(d_i\),根据容斥,答案为\(C_n^3 - \sum C_{d_i}^2\) 所以我们需要最小化\(\sum C_{d_i}^2\) 考 ...

  9. BZOJ 3171 循环格(费用流)

    题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...

随机推荐

  1. 在windows操作系统中,查询端口占用和清除端口占用的程序

    一.在windows操作系统中,查询端口占用和清除端口占用的程序 提升权限后用:netstat -b或用 1.查询端口占用的进程ID 点击"开始"-->"运行&qu ...

  2. Dubbo + Zookeeper 简单配置

    Dubbo + Zookeeper Zookeeper 下载及配置 下载到本机/usr/local目录 wget https://mirrors.tuna.tsinghua.edu.cn/apache ...

  3. springboot跳转jsp页面

    springboot支持jsp页面跳转 官方不推荐jsp的支持(jar包不支持jsp,jsp需要运行在servletContext中,war包需要运行在server服务器中如tomcat)官方推荐使用 ...

  4. laravel中的validate验证的使用案例:

    第一个是设置,第二个是直接调用.

  5. C# 处理 JSON 常用的帮助类

    C#请求接口的方法,具体代码: 首先需要添加引用和第三方的组件,具体如下: 引用命名空间: using System.IO; using Newtonsoft.Json.Linq; using Sys ...

  6. 网关-zuul介绍 第一篇 网关解决的问题

    基于网关,我们可以实现 限流,认证,监控,路由 等功能,这样说,我们可能觉得很生硬,那我们反过来推一下, 假如没有网关会怎么样?1 :客户端需要访问多个后端服务,则前端得存储多个后端的地址(ip+po ...

  7. 浅谈js异步

    大家都知道,js是一个单线程的语言(只有一个线程来执行js函数),所以如果某一个函数执行任务耗时比较长的话,就会造成阻塞,使得后续任务一直处于等待状态. 一.阻塞示例 function f1(){ ; ...

  8. Hibernate中用left join(左外连接)查询映射中没有关联关系的两个表记录问题

    一.问题背景 分账表split_summary结构如下: create table SPLIT_SUMMARY ( uuid VARCHAR2(32) not null, star_tdate VAR ...

  9. SQL基础三(例子)

    -----------聚合函数使用------------------------ --1.查询student表中所有学生人数 select count(stuno) from student --2 ...

  10. ARM寄存器总结:

    ARM有16个32位的寄存器(r0到r15). r15充当程序寄存器PC,r14(link register)存储子程序的返回地址,r13存储的是堆栈地址. ARM有一个当前程序状态寄存器:CPSR. ...