[WC2007] rock paper scissors

link

$solution:$

Consider how to find the number in the full three-membered ring in FIG consideration for $ (i, j, k) $, certainly if it is not a three-membered ring has one degree of $ 2 $, then the total number of $$ \ dbinom {n} {3} - \ sum_ {i = 1} ^ n \ dbinom {d_i} {2} $$ 

If the formula requires the minimum, then $$ min \ {\ sum_ {i = 1} ^ n \ dbinom {d_i} {2} \} = min \ {\ sum_ {i = 1} ^ n d_i ^ 2 \} $ $ 

Then the problem will be converted to oriented sides to each, such that each point of the square and the minimum degree, to choose one network flow problem solved considered. Maintenance squared difference in increments of $ 2,2 ^ ^ ^ 2-0 2-1 2-2 ^ ^ 2,3 ^ 2,4 ^ 2-3 ^ 2 $ 1 and so on, you can run the minimum cost maximum flow.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<climits>
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return f*ans;
}
const int MAXN=50001;
const int MAXM=301;
queue<int> que;
struct node{
    int u,v,w,cost,nex;
}x[MAXN<<1];
int head[MAXN],cnt,N,M,MM[MAXM][MAXM],S,T,INF=INT_MAX,Me[MAXN][MAXM];
void add(int u,int v,int w,int cost){
    x[cnt].u=u,x[cnt].v=v,x[cnt].w=w,x[cnt].cost=cost,x[cnt].nex=head[u],head[u]=cnt++;swap(u,v),w=0,cost=-cost;
    x[cnt].u=u,x[cnt].v=v,x[cnt].w=w,x[cnt].cost=cost,x[cnt].nex=head[u],head[u]=cnt++;return;
}
pair<int,int> pa[MAXN];
int num,dis[MAXN],vis[MAXN],MC;
bool bfs(){
    memset(vis,0,sizeof(vis)),memset(dis,127/3,sizeof(dis));int inf=dis[0];dis[S]=0;
    vis[S]=1;que.push(S);
    while(!que.empty()){
        int xx=que.front();que.pop();vis[xx]=0;
        for(int i=head[xx];i!=-1;i=x[i].nex){
            if(dis[x[i].v]>dis[xx]+x[i].cost&&x[i].w){
                dis[x[i].v]=dis[xx]+x[i].cost;
                if(!vis[x[i].v]) vis[x[i].v]=1,que.push(x[i].v);
            }
        }
    }return dis[T]!=inf;
}
int dfs(int u,int flow){
    if(u==T) return flow;int used=0;vis[u]=1;
    for(int i=head[u];i!=-1;i=x[i].nex){
        if(!vis[x[i].v]&&x[i].w&&dis[x[i].v]==dis[u]+x[i].cost){
            int slow=dfs(x[i].v,min(flow-used,x[i].w));used+=slow;MC+=slow*x[i].cost;
            x[i].w-=slow,x[i^1].w+=slow;
            if(flow==used) break;
        }
    }if(!used) dis[u]=-1;
    return used;
}
int Dinic(){
    int Ans=0;
    while(bfs()){memset(vis,0,sizeof(vis));Ans+=dfs(S,INF);}
    return Ans;
}
int Ans[MAXM][MAXM];
int GG[MAXM][MAXM],d[MAXN];
int calc(int x){if(x<2) return 0;return (x*(x-1))/2;}
int main(){
//    freopen("7.in","r",stdin);
    memset(head,-1,sizeof(head));
    N=read();
    for(int i=1;i<=N;i++) for(int j=1;j<=N;j++){
        int e=read();
        if(e==1) MM[i][j]=1;
        if(e==0) MM[i][j]=2;
    }
    num=N;
    for(int i=1;i<=N;i++){
        for(int j=i+1;j<=N;j++){
            pa[++num].first=i,pa[++num].second=j;GG[i][j]=num;
            if(MM[i][j]==1){add(num,i,1,0);continue;}
            if(MM[i][j]==2){add(num,j,1,0);continue;}
            add(num,i,1,0),add(num,j,1,0);
        }
    }
    for(int i=N+1;i<=num;i++) add(S,i,1,0);T=++num;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++) add(i,T,1,j*j-(j-1)*(j-1));
    }
    int G=Dinic();
    for(int i=0;i<cnt;i++) if(x[i].u>N&&x[i].v<=N) Me[x[i].u][x[i].v]=x[i].w;
    for(int i=1;i<=N;i++){
        for(int j=i+1;j<=N;j++){
            if(MM[i][j]==1){Ans[i][j]=1;continue;}
            if(MM[i][j]==2){Ans[i][j]=0;continue;}
            int las=GG[i][j];
//            printf("%d %d %d\n",las,i,j);
            if(Me[las][i]==1){Ans[i][j]=0;continue;}
            Ans[i][j]=1;continue;
        }
    }
    for(int i=1;i<=N;i++)
        for(int j=i+1;j<=N;j++) Ans[j][i]=Ans[i][j]^1;
    for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) if(Ans[i][j]) d[j]++;
    int res=(N*(N-1)*(N-2))/6;
    for(int i=1;i<=N;i++) res-=calc(d[i]);
    printf("%d\n",res);
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++) printf("%d ",Ans[i][j]);
        printf("\n");
    }return 0;
}/*3
0 1 2
0 0 2
2 2 0
*/
View Code

Guess you like

Origin www.cnblogs.com/si-rui-yang/p/12056459.html