zoukankan      html  css  js  c++  java
  • BZOJ2597: [Wc2007]剪刀石头布

    BZOJ2597: [Wc2007]剪刀石头布

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

    分析:

    • 好题。
    • 先是补集转化,求最少的非剪刀石头布情况。
    • 我们枚举那个赢了两次的人,可知总数就是(sumlimits _ {i=1}^{n}inom{w_i}{2})其中(w_i)为获胜场数。
    • 那么对于没打过比赛的两个人,新建点(tot)(S ightarrow tot) (tot)指向那两个点。
    • 然后每个人向(T)(n)边,费用为(inom{i}{2}-inom{i-1}{2})

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <set>
    using namespace std;
    #define N 11050
    #define M 500050
    #define inf 0x3f3f3f3f
    const int S=N-1,T=N-2;
    int head[N],to[M],nxt[M],flow[M],val[M],n,cnt=1;
    int dis[N],Q[N],path[N],vis[N];
    inline void add(int u,int v,int f,int c) {
    	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; val[cnt]=c;
    	to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; val[cnt]=-c;
    }
    bool spfa() {
    	memset(path,0,sizeof(path));
    	memset(dis,0x3f,sizeof(dis));
    	int l=0,r=0;
    	Q[r++]=S; dis[S]=0;
    	while(l!=r) {
    		int x=Q[l++]; if(l==S) l=0;
    		int i; vis[x]=0;
    		for(i=head[x];i;i=nxt[i]) if(dis[to[i]]>dis[x]+val[i]&&flow[i]) {
    			dis[to[i]]=dis[x]+val[i]; path[to[i]]=i^1;
    			if(!vis[to[i]]) {
    				vis[to[i]]=1; Q[r++]=to[i]; if(r==S) r=0;
    			}
    		}
    	}
    	return path[T]!=0;
    }
    int ek() {
    	int minc=0;
    	while(spfa()) {
    		int nf=inf;
    		int i;
    		for(i=T;i!=S;i=to[path[i]]) {
    			nf=min(nf,flow[path[i]^1]);
    		}
    		for(i=T;i!=S;i=to[path[i]]) {
    			flow[path[i]^1]-=nf;
    			flow[path[i]]+=nf;
    			minc+=nf*val[path[i]^1];
    		}
    	}
    	return minc;
    }
    int A[105][105],pp[105][105];
    int main() {
    	scanf("%d",&n);
    	int i,j;
    	for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&A[i][j]);
    	int tot=n;
    	for(i=1;i<=n;i++) {
    		for(j=i+1;j<=n;j++) if(A[i][j]==2) {
    			tot++;
    			add(tot,i,1,0);
    			pp[i][j]=cnt-1;
    			add(tot,j,1,0);
    			pp[j][i]=cnt-1;
    			add(S,tot,1,0);
    		}
    	}
    	for(i=1;i<=n;i++) {
    		int c=0;
    		for(j=1;j<=n;j++) {
    			if(A[i][j]==1) c++;
    		}
    		if(c) add(S,i,c,0);
    	}
    	for(i=1;i<=n;i++) {
    		for(j=1;j<=n;j++) {
    			add(i,T,1,j*(j-1)/2-(j-1)*(j-2)/2);
    		}
    	}
    	int ans=ek();
    	ans=n*(n-1)*(n-2)/6-ans;
    	printf("%d
    ",ans);
    	for(i=1;i<=n;i++) {
    		for(j=1;j<=n;j++) {
    			if(A[i][j]!=2) {
    				printf("%d ",A[i][j]);
    			}else {
    				if(i==j) printf("0 ");
    				else {
    					if(!flow[pp[i][j]]) printf("1 ");
    					else printf("0 ");
    				}
    			}
    		}
    		puts("");
    	}
    }
    
    
  • 相关阅读:
    spring,hibernate,spring框架整合
    python3安装pwntools
    分享一批大佬博客及学习网站
    jarvisoj--FindKeyWP
    pwntools的安装
    LibcSearcher 安装
    xctf pwn(新手练习)level3
    ret2libc3两种利用方法
    pwn函数调用
    Python知识点
  • 原文地址:https://www.cnblogs.com/suika/p/10205854.html
Copyright © 2011-2022 走看看