• 【网络流24题】分配问题(二分图最佳匹配)(费用流)


    【网络流24题】分配问题

    题目描述 Description

    有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为ij c 。试设计一个将
    n件工作分配给n个人做的分配方案,使产生的总效益最大。
    «编程任务:
    对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。

    输入描述 Input Description

    第1 行有1 个正整数n,表示有n件工作要分配给n 个人做。接下来的n 行中,每行有n 个整数 cij ,1≤i≤n,1≤j≤n,表示第i 个人做第j件工作产生的效益为cij

    输出描述 Output Description

    将计算出的最小总效益和最大总效益输出

    样例输入 Sample Input

    5
    2 2 2 1 2
    2 3 1 2 4
    2 0 1 1 1
    2 3 4 3 3
    3 2 1 2 1

    样例输出 Sample Output

    5
    14

    又是一道无数据范围的题目,无语了,开了2000

    这是道裸题吧,S向左边流量为1,费用为0,

    左边向右边,流量为1,费用a[i][j],

    右边向汇点,流量为1,费用为0。

      1 #include<cstring>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstdio>
      6 #include<queue>
      7 
      8 #define N 2007
      9 #define M 1000007
     10 #define inf 1000000007
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     16     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 int n,S,T;
     21 int cnt=1,head[N],rea[M],val[M],cost[M],next[M];
     22 int dis[N],flag[N],a[N][N];
     23 struct Node
     24 {
     25     int e,fa;
     26     void init(){e=fa=-1;}
     27 }pre[N];
     28 
     29 void add(int u,int v,int fee,int pay)
     30 {
     31     next[++cnt]=head[u];
     32     head[u]=cnt;
     33     rea[cnt]=v;
     34     val[cnt]=fee;
     35     cost[cnt]=pay;
     36 }
     37 void build(int k)
     38 {
     39     cnt=1,memset(head,-1,sizeof(head));
     40     for (int i=1;i<=n;i++)
     41         add(S,i,1,0),add(i,S,0,0);
     42     for (int i=1;i<=n;i++)
     43         add(i+n,T,1,0),add(T,i+n,0,0);
     44     for (int i=1;i<=n;i++)
     45         for (int j=1;j<=n;j++)
     46             add(i,j+n,1,a[i][j]*k),add(j+n,i,0,-a[i][j]*k);        
     47 }
     48 bool Spfa()
     49 {
     50     for (int i=S;i<=T;i++)
     51         dis[i]=inf,flag[i]=0,pre[i].init();
     52     queue<int>q;q.push(S);
     53     dis[S]=0,flag[S]=1;
     54     while(!q.empty())
     55     {
     56         int u=q.front();q.pop();
     57         for (int i=head[u];i!=-1;i=next[i])
     58         {
     59             int v=rea[i],fee=cost[i];
     60             if ((dis[v]>dis[u]+fee)&&val[i]>0)
     61             {
     62                 dis[v]=dis[u]+fee;
     63                 pre[v].e=i,pre[v].fa=u;
     64                 if (!flag[v])
     65                 {
     66                     flag[v]=1;
     67                     q.push(v);
     68                 }
     69             }
     70         }
     71         flag[u]=0;
     72     }
     73     if (dis[T]==inf) return 0;
     74     else return 1;
     75 }
     76 int mfmc()
     77 {
     78     int flow=0,res=0;
     79     while(Spfa())
     80     {
     81         int x=inf;
     82         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
     83         {
     84             int e=pre[i].e;
     85             x=min(x,val[e]);
     86         }
     87         flow+=x,res+=dis[T]*x;
     88         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
     89         {
     90             int e=pre[i].e;
     91             val[e]-=x,val[e^1]+=x;
     92         }
     93     }
     94     return res;
     95 }
     96 int main()
     97 {
     98     n=read(),S=0,T=n*2+1;
     99     for (int i=1;i<=n;i++)
    100         for (int j=1;j<=n;j++)
    101             a[i][j]=read();
    102     build(1);printf("%d
    ",mfmc());
    103     build(-1);printf("%d
    ",-mfmc());
    104 }
  • 相关阅读:
    洛谷 P2327 [SCOI2005]扫雷 题解
    P1388 算式 题解
    P1281 书的复制 题解
    P2896 [USACO08FEB]一起吃饭Eating Together 题解
    P1140 相似基因 题解
    变量的解构赋值
    let 和 const 命令
    第一阶段站立会议8
    第一阶段站立会议7
    第一阶段站立会议6
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7931814.html
Copyright © 2020-2023  润新知