• [网络流24题] 分配问题 (费用流)


    洛谷传送门 LOJ传送门

    同样是很裸的一个费用流,模型也很好想

    源点$S$向每个人连流量为$1$,费用为$0$的边,每个工作向汇点连流量为$1$,费用为$0$的边,代表每个人都只能被分配一个工作

    每个人可以在所有工作中任选,而一个工作只能被完成$1$次,所以每个人$i$和每个工作$j$之间连一条流量为$1$,费用为$c_{i,j}$的边

    然后上费用流就行了

      1 #include <vector>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define N1 205
      6 #define M1 50010
      7 #define ll long long
      8 #define dd double
      9 #define inf 0x3f3f3f3f
     10 using namespace std;
     11 
     12 int gint()
     13 {
     14     int ret=0,fh=1;char c=getchar();
     15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     17     return ret*fh;
     18 }
     19 
     20 int n,nn,S,T;
     21 
     22 
     23 int flow[N1][N1],cost[N1][N1],f[N1][N1],c[N1][N1];
     24 int que[M1],hd,tl,C[N1],F[N1],pre[N1];
     25 
     26 namespace S1{
     27 void bfs()
     28 {
     29     int x,i,v;
     30     memset(C,0x3f,sizeof(C)); memset(F,0,sizeof(F)); 
     31     hd=1,tl=0; que[++tl]=S; C[S]=0; F[S]=inf;
     32     while(hd<=tl)
     33     {
     34         x=que[hd++];
     35         for(v=1;v<=nn;v++)
     36         {
     37             if(!flow[x][v]) continue; 
     38             if(C[v]>C[x]+cost[x][v]) 
     39             {
     40                 C[v]=C[x]+cost[x][v];
     41                 F[v]=min(F[x],flow[x][v]);
     42                 que[++tl]=v; pre[v]=x;
     43             }
     44         }
     45     }
     46 } 
     47 void Dinic()
     48 {
     49     memcpy(cost,c,sizeof(c)); memcpy(flow,f,sizeof(f));
     50     int cash=0,tmp,x;
     51     while(1)
     52     {
     53         bfs(); if(!F[T]) break;
     54         for(x=T;x!=S;x=pre[x]) 
     55             flow[pre[x]][x]-=F[T],flow[x][pre[x]]+=F[T];
     56         cash+=C[T]*F[T];
     57     }
     58     printf("%d
    ",cash);
     59 }
     60 };
     61 
     62 namespace S2{
     63 void bfs()
     64 {
     65     int x,v;
     66     memset(C,-0x3f,sizeof(C)); memset(F,0,sizeof(F)); 
     67     hd=1,tl=0; que[++tl]=S; C[S]=0; F[S]=inf;
     68     while(hd<=tl)
     69     {
     70         x=que[hd++];
     71         for(v=1;v<=nn;v++)
     72         {
     73             if(!flow[x][v]) continue; 
     74             if(C[v]<C[x]+cost[x][v]) 
     75             {
     76                 C[v]=C[x]+cost[x][v];
     77                 F[v]=min(F[x],flow[x][v]);
     78                 que[++tl]=v; pre[v]=x;
     79             }
     80         }
     81     }
     82 } 
     83 void Dinic()
     84 {
     85     memcpy(cost,c,sizeof(c)); memcpy(flow,f,sizeof(f));
     86     int cash=0,tmp,x;
     87     while(1)
     88     {
     89         bfs(); if(!F[T]) break;
     90         for(x=T;x!=S;x=pre[x]) 
     91             flow[pre[x]][x]-=F[T],flow[x][pre[x]]+=F[T];
     92         cash+=C[T]*F[T];
     93     }
     94     printf("%d
    ",cash);
     95 }
     96 };
     97 
     98 
     99 int main()
    100 {
    101     scanf("%d",&n); nn=n*2+2;
    102     int i,j,v,ans; S=n+n+1,T=n+n+2;
    103     for(i=1;i<=n;i++) for(j=1;j<=n;j++) 
    104         scanf("%d",&c[i][n+j]),c[n+j][i]=-c[i][n+j],f[i][n+j]=1;
    105     for(i=1;i<=n;i++) f[S][i]=1,f[n+i][T]=1;
    106     S1::Dinic(); S2::Dinic();
    107     return 0;
    108 }
  • 相关阅读:
    深入理解sizeof
    trie树详解
    高精度计算
    编写高效的Android代码
    Android Architecture
    AIDL Android中的远程接口
    性能测试常见术语
    软件与软件测试相关
    注解实现Springmvc+jsp步骤
    非注解实现SpringMvc+JSP (一般用不到 主要用于了解研究底层)
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10283836.html
Copyright © 2020-2023  润新知