zoukankan      html  css  js  c++  java
  • BZOJ 2324 营救皮卡丘

    http://www.lydsy.com/JudgeOnline/problem.php?id=2324

    思路:最小费用最大流

    考虑设数组d[k][i][j],代表只用前k个城市,i到j的最短路

    然后可以这样建图

    S->0 流量为K,费用为0

    i->i+n 流量为inf,费用为0

    i+n->T 流量为1

    i+n->j 流量为inf,费用为d[j][i][j]

    S->i  流量为1,费用为0 代表如果一个人到了i城市,它可以继续走,从而续出来的一个新流量。

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 #define inf 0x7fffffff
     7 int d[205][205][205],a[205][205],K;
     8 int tot,go[200005],next[200005],first[200005],cost[200005],flow[200005];
     9 int op[200005],dis[200005],c[200005],vis[200005],edge[200005],from[200005];
    10 int S,T,n,m,ans;
    11 int read(){
    12     char ch=getchar();int t=0,f=1;
    13     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    14     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    15     return t*f;
    16 }
    17 void insert(int x,int y,int z,int l){
    18     tot++;
    19     go[tot]=y;
    20     next[tot]=first[x];
    21     first[x]=tot;
    22     flow[tot]=z;
    23     cost[tot]=l;
    24 }
    25 void add(int x,int y,int z,int l){
    26     insert(x,y,z,l);op[tot]=tot+1;
    27     insert(y,x,0,-l);op[tot]=tot-1;
    28 }
    29 bool spfa(){
    30     for (int i=0;i<=T;i++)
    31      dis[i]=0x3f3f3f3f,vis[i]=0;
    32     int h=1,t=1;c[1]=S;vis[S]=1;dis[S]=0;
    33     while (h<=t){
    34         int now=c[h++];
    35         for (int i=first[now];i;i=next[i]){
    36             int pur=go[i];
    37             if (dis[pur]>dis[now]+cost[i]&&flow[i]){
    38                 dis[pur]=dis[now]+cost[i];
    39                 edge[pur]=i;
    40                 from[pur]=now;
    41                 if (vis[pur]) continue;
    42                 vis[pur]=1;
    43                 c[++t]=pur;
    44             }
    45         }
    46         vis[now]=0;
    47     }
    48     return dis[T]!=0x3f3f3f3f;
    49 }
    50 void updata(){
    51     int mn=0x7ffffff;
    52     for (int i=T;i!=S;i=from[i]){
    53         mn=std::min(mn,flow[edge[i]]);
    54     }
    55     for (int i=T;i!=S;i=from[i]){
    56         ans+=mn*cost[edge[i]];
    57         flow[edge[i]]-=mn;
    58         flow[op[edge[i]]]+=mn;
    59     }
    60 }
    61 int main(){
    62     n=read();m=read();K=read();
    63     for (int i=0;i<=n;i++)
    64      for (int j=0;j<=n;j++)
    65       if (i!=j){
    66             a[i][j]=0x3f3f3f3f;
    67       }else
    68             a[i][j]=0;
    69     for (int i=1;i<=m;i++){
    70         int u=read(),v=read(),w=read();
    71         a[u][v]=std::min(a[u][v],w);
    72         a[v][u]=std::min(a[v][u],w);
    73     }
    74     for (int k=0;k<=n;k++){
    75         for (int i=0;i<=n;i++)
    76          for (int j=0;j<=n;j++)
    77           a[i][j]=std::min(a[i][k]+a[k][j],a[i][j]);
    78         for (int i=0;i<=n;i++)
    79          for (int j=0;j<=n;j++)
    80           d[k][i][j]=a[i][j];  
    81     }
    82     S=2*n+2;T=S+1;
    83     add(S,0,K,0);
    84     for (int i=0;i<=n;i++)
    85      add(i,i+n+1,inf,0);
    86     for (int i=0;i<=n;i++)
    87      add(i,T,1,0);
    88     for (int i=0;i<=n;i++)
    89      add(S,i+n+1,1,0);
    90     for (int i=0;i<=n;i++)
    91      for (int j=i+1;j<=n;j++)
    92       if (d[j][i][j]<0x3f3f3f3f)
    93       add(i+n+1,j,inf,d[j][i][j]);
    94     while (spfa()) updata();
    95     printf("%d
    ",ans);      
    96 }
  • 相关阅读:
    项目管理实践【三】每日构建【Daily Build Using CruiseControl.NET and MSBuild】
    项目管理实践教程二、源代码控制【Source Control Using VisualSVN Server and TortoiseSVN】
    javascript 容易忽略或者误用的七个基础知识点
    未来的路还很长
    Nodejs
    CSS浏览器兼容性相关
    HTML5
    一些正则
    Sublime 使用
    Array.prototype.slice.call(arguments,1)
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5615310.html
Copyright © 2011-2022 走看看