• 【网络流24题】分配问题 最小最大费用最大流


    有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为Cij 。试设计一个将 n件工作分配给n个人做的分配方案,使产生的总效益最大。 编程任务: 对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。
    由文件input.txt提供输入数据。文件的第1 行有1 个正整数n,表示有n件工作要分配 给n 个人做。接下来的n 行中,每行有n 个整数Cij ,1≤i≤n,1≤j≤n(n<=100),表示第i 个人做 第j件工作产生的效益为Cij。
    程序运行结束时,将计算出的最小总效益和最大总效益输出到文件output.txt中。

    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

     

    题解:

    (S,人,1,0) (工作,T,1,0) (人,工作,INF,map[i][j])

    然后最小费用就是跑spfa增广最小cost

    最大费用就是把map[i][j]设成负的,然后一样跑spfa,答案即为-ans

    可笑的是傻逼的我搞了个层次网络,然后挂了.

     

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int N=505,INF=1999999999;
     7 int gi(){
     8     int str=0;char ch=getchar();
     9     while(ch>'9'||ch<'0')ch=getchar();
    10     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
    11     return str;
    12 }
    13 int n,S=0,T,num=1,head[N];
    14 struct Lin{
    15     int next,to,dis,cost;
    16 }a[N*N];
    17 int map[101][101];
    18 void init(int x,int y,int dis,int cost){
    19     a[++num].next=head[x];
    20     a[num].to=y;
    21     a[num].dis=dis;
    22     a[num].cost=cost;
    23     head[x]=num;
    24     a[++num].next=head[y];
    25     a[num].to=x;
    26     a[num].dis=0;
    27     a[num].cost=-cost;
    28     head[y]=num;
    29 }
    30 bool vis[N];int q[N*10],pre[N],f[N],ans=0;
    31 bool spfa()
    32 {
    33     for(int i=0;i<=T;i++)f[i]=INF,vis[i]=false;
    34     q[1]=S;f[S]=0;int x,u,t=0,sum=1;
    35     while(t!=sum)
    36     {
    37         x=q[++t];
    38         for(int i=head[x];i;i=a[i].next){
    39             u=a[i].to;
    40             if(a[i].dis<=0)continue;
    41             if(f[x]+a[i].cost<f[u]){
    42                 f[u]=f[x]+a[i].cost;
    43                 pre[u]=i;
    44                 if(!vis[u])vis[u]=true,q[++sum]=u;
    45             }
    46         }
    47         vis[x]=false;
    48     }
    49     if(f[T]!=INF)
    50     ans+=f[T];
    51     return f[T]!=INF;
    52 }
    53 void Change()
    54 {
    55     int x=T;
    56     while(x){
    57         a[pre[x]].dis--;
    58         a[pre[x]^1].dis++;
    59         x=a[pre[x]^1].to;
    60     }
    61 }
    62 void Clear(){
    63     memset(head,0,sizeof(head));
    64     num=1;ans=0;
    65 }
    66 int main()
    67 {
    68     n=gi();T=(n<<1)+1;
    69     for(int i=1;i<=n;i++)init(S,i,1,0),init(i+n,T,1,0);
    70     for(int i=1;i<=n;i++){
    71         for(int j=1;j<=n;j++){
    72             map[i][j]=gi();init(i,j+n,INF,map[i][j]);
    73         }
    74     }
    75     while(spfa()){
    76         Change();
    77     }
    78     printf("%d
    ",ans);
    79     Clear();
    80     for(int i=1;i<=n;i++)init(S,i,1,0),init(i+n,T,1,0);
    81     for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)init(i,j+n,INF,-map[i][j]);
    82     while(spfa()){
    83         Change();
    84     }
    85     printf("%d",-ans);
    86     return 0;
    87 }

     

     

  • 相关阅读:
    编程题目: PAT 1012. 数字分类 (20)
    编程题目: PAT 1011. A+B和C (15)
    Poj3683(2-set
    LightOJ 1427(AC自动机
    UVA 11990(BIT套treap
    网络流汇总....
    10月——备战区域赛
    去掉ubuntu的文件管理器中“位置”栏里的无用标签
    Poj 2104(主席树入门
    Poj 1568(极大极小搜索
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6877808.html
Copyright © 2020-2023  润新知