zoukankan      html  css  js  c++  java
  • [CQOI2012] 交换棋子 (费用流)

    $pdfspace solution$    link 

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<climits>
    #include<queue> 
    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;
    }
    queue<int> que;
    const int MAXN=100001;
    const int N=1001;
    struct node{
        int u,v,cost,w,nex;
    }x[MAXN<<2];
    int head[MAXN],S,T,cnt,dis[MAXN],vis[MAXN],cost,INF=INT_MAX;
    void add(int u,int v,int cost,int w){
    //    printf("u:%d v:%d cost:%d w:%d
    ",u,v,cost,w);
        x[cnt].u=u,x[cnt].v=v,x[cnt].cost=cost,x[cnt].w=w,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].cost=cost,x[cnt].w=w,x[cnt].nex=head[u],head[u]=cnt++;
    }
    bool spfa(){
        memset(dis,127/3,sizeof(dis)),memset(vis,0,sizeof(vis));
        int inf=dis[0];dis[S]=0,vis[S]=1,que.push(S);
        while(!que.empty()){
            int xx=que.front();que.pop();
            for(int i=head[xx];i!=-1;i=x[i].nex){
                if(x[i].w&&dis[x[i].v]>dis[xx]+x[i].cost){
                    dis[x[i].v]=dis[xx]+x[i].cost;
                    if(!vis[x[i].v]) vis[x[i].v]=1,que.push(x[i].v);
                }
            }vis[xx]=0;
        }return dis[T]!=inf;
    }
    int dfs(int u,int flow){
    //    printf("u:%d flow:%d
    ",u,flow);
        if(u==T) return flow;
        int used=0;vis[u]=1;
        for(int i=head[u];i!=-1;i=x[i].nex){
            if(x[i].w&&dis[x[i].v]==dis[u]+x[i].cost&&!vis[x[i].v]){
                int slow=dfs(x[i].v,min(flow-used,x[i].w));used+=slow;
                x[i].w-=slow,x[i^1].w+=slow;
                cost+=slow*x[i].cost;
                if(used==flow) break;
            }
        }if(!used) dis[u]=-1;
        vis[u]=0;
        return used;
    }
    int dinic(){
        int ans=0;cost=0;
        while(spfa()){memset(vis,0,sizeof(vis)),ans+=dfs(S,INF);}
        return ans;
    }
    char A[N][N],B[N][N],lim[N][N];
    int n,m,sum;
    int dx[8]={1,1,1,-1,-1,-1,0,0};
    int dy[8]={1,0,-1,1,0,-1,1,-1};
    int Q(int x,int y){return (x-1)*m+y;}
    int main(){
    //    freopen("8.in","r",stdin);
        memset(head,-1,sizeof(head));
        n=read(),m=read();S=0,T=n*m*3+1;
        for(int i=1;i<=n;i++) scanf("%s",A[i]+1);
        for(int i=1;i<=n;i++) scanf("%s",B[i]+1);
        for(int i=1;i<=n;i++) scanf("%s",lim[i]+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(A[i][j]==B[i][j]&&A[i][j]==1) continue;
                A[i][j]-='0',B[i][j]-='0',lim[i][j]-='0';
                if(A[i][j]==B[i][j]){
                    
                        add(Q(i,j),Q(i,j)+n*m,0,lim[i][j]/2);
                        add(Q(i,j)+2*n*m,Q(i,j),0,lim[i][j]);
                    
                    continue;
                }
                if(A[i][j]==1){
                    sum++;
                    add(S,Q(i,j),0,1);
                    add(Q(i,j),Q(i,j)+n*m,0,(lim[i][j]+1)/2);
                    add(Q(i,j)+2*n*m,Q(i,j),0,(lim[i][j]-1)/2);
                    continue; 
                }
                if(B[i][j]==1){
                    add(Q(i,j),Q(i,j)+n*m,0,(lim[i][j]-1)/2);
                    add(Q(i,j)+2*n*m,Q(i,j),0,(lim[i][j]+1)/2);
                    add(Q(i,j),T,0,1);
                }
            }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                for(int k=0;k<8;k++){
                    int bx=i+dx[k],by=j+dy[k];
                    if(bx>=1&&bx<=n&&by>=1&&by<=m){
                        add(Q(i,j)+n*m,Q(bx,by)+2*n*m,1,INF);
                    } 
                } 
            }
        }
        int Ans=dinic();
        if(Ans!=sum){printf("-1");return 0;}
        printf("%d
    ",cost);
    }/*
    1 2
    1 0
    0 1
    1 1
    */
    View Code
  • 相关阅读:
    2019 Multi-University Training Contest 4
    AC自动机
    trie
    Contest1802
    蓝桥杯-某电视台举办了低碳生活大奖赛
    蓝桥杯-有一群海盗(不多于20人),在船上比拼酒量
    蓝桥杯-福尔摩斯到某古堡探险
    蓝桥杯-标题:字符串比较
    蓝桥杯-题目:猜算式
    蓝桥杯-标题:算年龄
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10543371.html
Copyright © 2011-2022 走看看