zoukankan      html  css  js  c++  java
  • P4249 [WC2007]剪刀石头布

    有一个竞赛图,要给一些边定向,求三元环最多的数量

    反过来考虑最少的不是环的三个点(称为不好的环),一定有一个点有2条入边,一个点有2条出边,一个点1入边1出边

    可以对每一个不好的环只记录入边为2的点,那么不好的环有$sum C_^2$个,其中$deg_i$是$i$的入度

    因为$C_^2=x(x-1)/2$,差分后导数$>0$,所以可以费用流,就做完了

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    typedef long long ll;
    il int gi(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    int a[101][101],num[101][101],cnt,o[101][101],S,T;
    int fir[6000],dis[1000010],nxt[1000010],w[1000010],cost[100010],id=1;
    il vd link(int a,int b,int c){
        nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=1,cost[id]=c;
        nxt[++id]=fir[b],fir[b]=id,dis[id]=a,cost[id]=-c;
    }
    il bool Mincost(int&total){
        static int dist[6000],lst[6000],inq[6000],que[6000],hd,tl;
        hd=tl=0;memset(dist,63,4*(cnt+1));dist[S]=0;inq[S]=1;que[tl++]=S;
        while(hd^tl){
            int x=que[hd];
            for(int i=fir[x];i;i=nxt[i])
                if(w[i]&&dist[dis[i]]>dist[x]+cost[i]){
                    dist[dis[i]]=dist[x]+cost[i];lst[dis[i]]=i;
                    if(!inq[dis[i]]){
                        inq[dis[i]]=1,que[tl++]=dis[i];
                        if(tl==6000)tl=0;
                    }
                }
            ++hd;if(hd==6000)hd=0;
            inq[x]=0;
        }
        if(dist[T]==dist[0])return 0;
        for(int i=lst[T];i;i=lst[dis[i^1]])w[i]=0,w[i^1]=1,total+=cost[i];
        return 1;
    }
    int main(){
        int n=gi();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                a[i][j]=gi();
        cnt=n;
        S=++cnt,T=++cnt;
        for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j){
                num[i][j]=++cnt;
                if(a[i][j]==0)link(S,i,0);
                else if(a[i][j]==1)link(S,j,0);
                else link(S,num[i][j],0),o[i][j]=id+1,link(num[i][j],i,0),link(num[i][j],j,0);
            }
        for(int i=1;i<=n;++i)
            for(int j=n;j;--j)
                link(i,T,j-1);
        int ans=0;while(Mincost(ans));
        printf("%d
    ",n*(n-1)*(n-2)/6-ans);
        for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j)
                if(a[i][j]==2)a[i][j]=w[o[i][j]],a[j][i]=!a[i][j];
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j)printf("%d ",a[i][j]);
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    c#——总结两种方式下载模板
    c#——NPOL下载
    c#——泛型类型约束
    Oracle 数据类型
    软件测试绩效评估点
    读《没有带不好的员工》总结
    安装jenkins,配置pipline 运行docker
    K8S pv与pvc匹配不到的坑
    jenkins 在pipeline中运行docker镜像执行测试代码
    k8s 储存卷的定义与使用
  • 原文地址:https://www.cnblogs.com/xzz_233/p/10042292.html
Copyright © 2011-2022 走看看