网络流24题之分配问题

题目链接:传送门

这道题和运输问题也是贼相似的,几乎一模一样
详细见网络流24题之分配问题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int read(){
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9')
        f=(c=='-')?-1:1,c=getchar();
    while(c>='0'&&c<='9')
        x=x*10+c-'0',c=getchar();
    return x*f;
}
struct node{
    int to,next,v,w;
}a[100001];
int dis[1001],f[1001],pre[1001],fa[1001],head[1001],cnt,n,m,s,t,z,w,ans,ans1;
void add(int x,int y,int c,int v){
    a[++cnt].to=y;
    a[cnt].next=head[x];
    a[cnt].v=c;
    a[cnt].w=v;
    head[x]=cnt;
}
queue<int> q ;
int spfa() {
    memset(dis,127,sizeof(dis));
    memset(f,0,sizeof(f));
    q.push(s);
    f[s]=1;
    int inf=dis[1];
    dis[s]=0;
    while(!q.empty()) {
        int now=q.front();
        q.pop();
        f[now]=0;
        for(int i=head[now]; i; i=a[i].next) {
            int v=a[i].to;
            if(dis[v]>dis[now]+a[i].w&&a[i].v) {
                dis[v]=dis[now]+a[i].w;
                fa[v]=now;
                pre[v]=i;
                if(!f[v])
                    q.push(v),f[v]=1;
            }
        }
    }
    if(dis[t]!=inf)
        return 1;
    return 0;
}
void answer() {
    ans=0,ans1=0;
    while(spfa()) {
        int minx=2147483647;
        for(int i=t; i!=s; i=fa[i])
            minx=min(minx,a[pre[i]].v);
        ans+=minx,ans1+=dis[t]*minx;
        for(int i=t; i!=s; i=fa[i]) {
            a[pre[i]].v-=minx;
            if(pre[i]%2)
                a[pre[i]+1].v+=minx;
            else
                a[pre[i]-1].v+=minx;
        }
    }
}
int x[1001][1001];
int main(){
    n=read();
    t=n*2+1;
    for(int i=1;i<=n;i++)
        add(s,i,1,0),add(i,s,0,0);
    for(int i=1;i<=n;i++)
        add(i+n,t,1,0),add(t,i+n,0,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            x[i][j]=read(),add(i,j+n,10000000,x[i][j]),add(j+n,i,0,-x[i][j]);
    answer();
    printf("%d\n",ans1);
    memset(head,0,sizeof(head)),cnt=0;
    for(int i=1;i<=n;i++)
        add(s,i,1,0),add(i,s,0,0);
    for(int i=1;i<=n;i++)
        add(i+n,t,1,0),add(t,i+n,0,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            add(i,j+n,1,-x[i][j]),add(j+n,i,0,x[i][j]);
    answer();
    printf("%d",-ans1);
}

猜你喜欢

转载自www.cnblogs.com/hbxblog/p/9716455.html
今日推荐