传送门

解题思路

  考虑全集-不能构成三元环的个数。如果三个点不能构成三元环,一定有一个点的入度为\(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]剪刀石头布(费用流)的更多相关文章

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

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

  2. bzoj 2597 [Wc2007]剪刀石头布——费用流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 三个人之间的关系,除了“剪刀石头布”,就是有一个人赢了2局:所以考虑算补集,则每个人对 ...

  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. HTTP详解教程 / HTTP 响应头信息 HTTP 响应头信息

    HTTP请求头提供了关于请求,响应或者其他的发送实体的信息. 在本章节中我们将具体来介绍HTTP响应头信息.直线电机哪家好 应答头 说明 Allow 服务器支持哪些请求方法(如GET.POST等). ...

  2. epoll学习

    一.epoll_create #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags) ...

  3. DM9000驱动网卡编程

    DM9000数据发送编程: static int dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned l ...

  4. JavaScript 六种继承方式

    title: JS的六种继承方式 date: 2017-06-27 05:55:49 tags: JS categories: 学习 --- 继承是面向对象编程中又一非常重要的概念,JavaScrip ...

  5. Random Point in Triangle

    题目链接 题意:多组输入三角形各个顶点坐标p1,p2,p3,在三角形中任取一点p,计算 期望E=max(S(p,p1,p2),max(S(p,p1,p3),S(p,p2,p3))); 思路:用随机数找 ...

  6. 分布式系统理论进阶7:Paxos变种和优化

    本文转自:https://www.cnblogs.com/bangerlee/p/6189646.html 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...

  7. tomcat 高并发

    转自 http://blog.csdn.net/feng27156/article/details/19420695 一.容器简化了程序员自身的多线程编程. 各种Web容器,如Tomcat,Resio ...

  8. sql格式化工具推荐

    还在为上百行甚至上千行冗余的sql烦恼吗?这里推荐一款在线美化sql的工具 工具地址:http://www.matools.com/sql 怎么样,黑屏界面是不是带有满满的黑科技感? 该工具支持ora ...

  9. 兼容iphone x刘海的正确姿势

    在 ios 11 中我们可以使用 viewport-fit=cover + safe-area-inset-*. 那么是不是 ios11 以下就用不了这些了呢?是的,但你见过 iphone x+ 有 ...

  10. php打包下载文件

    使用前请先开启:查看下php.ini里面的extension=php_zip.dll前面的分号有没有去掉; $zip=new \ZipArchive(); $zifile = 'download/' ...