zoukankan      html  css  js  c++  java
  • [BZOJ1070][SCOI2007]修车 费用流

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1070

    这种资源分配,平衡下最优解的题目好多都可以建图跑。要把车分配给修车师傅这种模式,想到网络流,又因为要修的车数N不会变,相当于总流量固定,则考虑费用流。但是直接考虑师傅修车是不好做的,我们反过来考虑车被师傅修,接下来就是神奇的建图。

    考虑车对答案的贡献,假设第i个车是第j个师傅修的倒数第k个车,于是它的贡献就是Ti[i][j]*k。

    然后考虑第i个车对可能的情况连边,xjb建一建就出来了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 using namespace std;
     6 const int INF=1<<30;
     7 int inline readint(){
     8     int Num;char ch;
     9     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
    10     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
    11     return Num;
    12 }
    13 int N,M;
    14 int Ti[65][15];
    15 int S,T;
    16 int to[100000],ne[100000],c[100000],w[100000],fir[1000],cnt=0;
    17 void add(int a,int b,int x,int y){
    18     to[cnt]=b,c[cnt]=x,w[cnt]=y,ne[cnt]=fir[a],fir[a]=cnt++;
    19     to[cnt]=a,c[cnt]=0,w[cnt]=-y,ne[cnt]=fir[b],fir[b]=cnt++;
    20 }
    21 int dis[1000],pre[1000];
    22 bool in[1000];
    23 queue <int> q;
    24 bool spfa(){
    25     memset(dis,127/3,sizeof(dis));
    26     dis[S]=0;
    27     in[S]=true;
    28     q.push(S);
    29     int u;
    30     while(!q.empty()){
    31         u=q.front();
    32         q.pop();
    33         in[u]=false;
    34         for(int i=fir[u];i!=-1;i=ne[i]){
    35             int v=to[i];
    36             if(dis[v]>dis[u]+w[i]&&c[i]){
    37                 dis[v]=dis[u]+w[i];
    38                 pre[v]=i;
    39                 if(!in[v]){
    40                     q.push(v);
    41                     in[v]=true;
    42                 }
    43             }
    44         }
    45     }
    46     return dis[T]!=dis[0];
    47 }
    48 int Mcmf(){
    49     int cost=0;
    50     pre[S]=-1;
    51     while(spfa()){
    52         int f=INF;
    53         for(int i=pre[T];i!=-1;i=pre[to[i^1]]) f=min(f,c[i]);
    54         for(int i=pre[T];i!=-1;i=pre[to[i^1]]){
    55             c[i]-=f;
    56             c[i^1]+=f;
    57         }
    58         cost+=f*dis[T];
    59     }
    60     return cost;
    61 }
    62 int main(){
    63     M=readint();
    64     N=readint();
    65     for(int i=1;i<=N;i++)
    66         for(int j=1;j<=M;j++)
    67             Ti[i][j]=readint();
    68     memset(fir,-1,sizeof(fir));
    69     S=(M+1)*N+1;
    70     T=(M+1)*N+2;
    71     for(int i=1;i<=N;i++) add(S,N*M+i,1,0);
    72     for(int i=1;i<=N*M;i++) add(i,T,1,0);
    73     for(int i=1;i<=N;i++)
    74         for(int j=1;j<=M;j++)
    75             for(int k=1;k<=N;k++)
    76                 add(N*M+i,(j-1)*N+k,1,Ti[i][j]*k);
    77     printf("%.2lf
    ",(double)Mcmf()/N);
    78     return 0;
    79 }
  • 相关阅读:
    (二分)进击的奶牛
    (二分)木材加工
    (简单并查集)The Suspects
    (递归)集合划分
    (简单并查集)How many tables?
    Wireless Network(并查集)
    (并查集)连通块中点的数量
    2019.04.08 电商17 购物车模型
    2019.04.08 电商 16 地址管理2
    2019.04.07 电商15 地址管理
  • 原文地址:https://www.cnblogs.com/halfrot/p/7588845.html
Copyright © 2011-2022 走看看