• 分配问题


    几乎是个板子,跟游戏几乎是重题。

    将每行建点,每列建点,这样可以保证每行每列都只有一个。

    格点拆掉,算个费用流就好了。

    看代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 1e9
    const int maxn=100005;
    int beg[maxn],nex[maxn],to[maxn],w[maxn],f[maxn],e;
    inline void add(int x,int y,int z,int c){
        nex[e]=beg[x];beg[x]=e;
        to[e]=y;f[e]=z;w[e]=c;e++;
    }
    int n,t,a[105][105];
    inline int read(){
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=(x<<1)+(x<<3)+c-'0';
            c=getchar();
        }
        return x*f;
    }
    int dis[maxn],vis[maxn],flow[maxn],pre[maxn],las[maxn];
    queue<int>q;
    inline int spfa(){
        //puts("spfa");
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        while(!q.empty())q.pop();
        dis[0]=0;
        vis[0]=1;
        flow[0]=inf;
        pre[t]=-1;
        q.push(0);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            //printf("%d
    ",x);
            vis[x]=0;
            for(int i=beg[x];~i;i=nex[i])
                if(f[i]&&dis[to[i]]>dis[x]+w[i]){
                    dis[to[i]]=dis[x]+w[i];
                    pre[to[i]]=x;
                    las[to[i]]=i;
                    flow[to[i]]=min(flow[x],f[i]);
                    if(!vis[to[i]]){
                        vis[to[i]]=1;
                        q.push(to[i]);
                    }
                }
        }
        //printf("%d
    ",flow[t]);
        return pre[t]!=-1;
    }
    int main(){
        memset(beg,-1,sizeof(beg));
        n=read();
        int x,cnt=0,pos;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                a[i][j]=read(),cnt++;
                add(cnt,cnt+n*n,1,a[i][j]);
                add(cnt+n*n,cnt,0,-a[i][j]);
            }
        cnt=2*n*n;
        t=++cnt;
        for(int i=1;i<=n;i++){
            cnt++;
            add(0,cnt,1,0);
            add(cnt,0,0,0);
            for(int j=1;j<=n;j++){
                pos=(i-1)*n+j;
                add(cnt,pos,inf,0);
                add(pos,cnt,0,0);
            }
        }
        for(int j=1;j<=n;j++){
            cnt++;
            add(cnt,t,1,0);
            add(t,cnt,0,0);
            for(int i=1;i<=n;i++){
                pos=(i-1)*n+j+n*n;
                add(pos,cnt,inf,0);
                add(cnt,pos,0,0);
            }
        }
        int maxflow=0;
        while(spfa()){
            maxflow+=flow[t]*dis[t];
            pos=t;
            while(pos!=0){
                f[las[pos]]-=flow[t];
                f[las[pos]^1]+=flow[t];
                pos=pre[pos];
            }
        }
        printf("%d
    ",maxflow);
        memset(beg,-1,sizeof(beg));
        e=cnt=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                cnt++;
                add(cnt,cnt+n*n,1,-a[i][j]);
                add(cnt+n*n,cnt,0,a[i][j]);
            }
        cnt=2*n*n;
        t=++cnt;
        for(int i=1;i<=n;i++){
            cnt++;
            add(0,cnt,1,0);
            add(cnt,0,0,0);
            for(int j=1;j<=n;j++){
                pos=(i-1)*n+j;
                add(cnt,pos,inf,0);
                add(pos,cnt,0,0);
            }
        }
        for(int j=1;j<=n;j++){
            cnt++;
            add(cnt,t,1,0);
            add(t,cnt,0,0);
            for(int i=1;i<=n;i++){
                pos=(i-1)*n+j+n*n;
                add(pos,cnt,inf,0);
                add(cnt,pos,0,0);
            }
        }
        maxflow=0;
        while(spfa()){
            maxflow-=flow[t]*dis[t];
            pos=t;
            while(pos!=0){
                f[las[pos]]-=flow[t];
                f[las[pos]^1]+=flow[t];
                pos=pre[pos];
            }
        }
        printf("%d
    ",maxflow);
        return 0;
    }

    深深地感到自己的弱小。

  • 相关阅读:
    SEO--我们是不是走错了路?
    Android中的几种网络请求方式详解 .
    Android中文URL乱码问题 解决
    Oracle的Move操作
    JavaScript取DOM中下拉框的选中值
    JSP中直接用正则表达式校验
    Oracle SQL查询,日期过滤条件要注意的一点
    Oracle Decode行变列
    strcpy和memcpy的区别
    static作用(修饰函数、局部变量、全局变量)
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12437083.html
Copyright © 2020-2023  润新知