zoukankan      html  css  js  c++  java
  • bzoj3876: [Ahoi2014&Jsoi2014]支线剧情(上下界费用流)

    传送门

    一道题让我又要学可行流又要学zkw费用流……

    考虑一下,原题可以转化为一个有向图,每次走一条路径,把每一条边都至少覆盖一次,求最小代价

    因为一条边每走过一次,就要付出一次代价

    那不就是费用流了么

    我们定义每走一次都会对一条边增加1的流量,1然后费用为时间

    那么把下界设为1,上界设为inf,跑一个最小费用可行流就可以了

    ps:不会可行流的可以去看看这个博客,我觉得写得很不错->这里

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #define inf 0x3f3f3f3f
     7 using namespace std;
     8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     9 char buf[1<<21],*p1=buf,*p2=buf;
    10 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    11 inline int read(){
    12     #define num ch-'0'
    13     char ch;bool flag=0;int res;
    14     while(!isdigit(ch=getc()))
    15     (ch=='-')&&(flag=true);
    16     for(res=num;isdigit(ch=getc());res=res*10+num);
    17     (flag)&&(res=-res);
    18     #undef num
    19     return res;
    20 }
    21 const int N=505,M=100005;
    22 int head[N],Next[M],ver[M],edge[M],flow[M],tot=1;
    23 int dis[N],vis[N],S,T,ans;
    24 queue<int> q;
    25 inline void add(int u,int v,int e,int f){
    26     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e,flow[tot]=f;
    27     ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=-e,flow[tot]=0;
    28 }
    29 bool spfa(){
    30     memset(dis,-1,sizeof(dis));
    31     memset(vis,0,sizeof(vis));
    32     q.push(T),dis[T]=0,vis[T]=1;
    33     while(!q.empty()){
    34         int u=q.front();q.pop();vis[u]=0;
    35         for(int i=head[u];i;i=Next[i])
    36         if(flow[i^1]){
    37             int v=ver[i],e=edge[i];
    38             if(dis[v]<0||dis[v]>dis[u]-e){
    39                 dis[v]=dis[u]-e;
    40                 if(!vis[v]) vis[v]=1,q.push(v);
    41             }
    42         }
    43     }
    44     return ~dis[S];
    45 }
    46 int dfs(int u,int limit){
    47     if(!limit) return 0;
    48     if(u==T) return vis[T]=1,limit;
    49     int fl=0,f;vis[u]=1;
    50     for(int i=head[u];i;i=Next[i]){
    51         int v=ver[i];
    52         if(dis[v]==dis[u]-edge[i]&&!vis[v]&&(f=dfs(v,min(limit,flow[i])))){
    53             fl+=f,limit-=f;
    54             ans+=f*edge[i];
    55             flow[i]-=f,flow[i^1]+=f;
    56             if(!limit) break;
    57         }
    58     }
    59     return fl;
    60 }
    61 void zkw(){
    62     while(spfa()){
    63         vis[T]=1;
    64         while(vis[T])
    65         memset(vis,0,sizeof(vis)),dfs(S,inf);
    66     }
    67 }
    68 int d[N],n;
    69 int main(){
    70     //freopen("testdata.in","r",stdin);
    71     n=read();
    72     for(int i=1;i<=n;++i){
    73         int t=read();
    74         while(t--){
    75             int x=read(),y=read();
    76             --d[i],++d[x],ans+=y;
    77             add(i,x,y,inf);
    78         }
    79     }
    80     S=0,T=n+2;
    81     for(int i=2;i<=n;++i) add(i,n+1,0,inf);
    82     for(int i=1;i<=n;++i){
    83         if(d[i]>0)add(S,i,0,d[i]);
    84         if(d[i]<0)add(i,T,0,-d[i]);
    85     }
    86     add(n+1,1,0,inf);
    87     zkw();
    88     printf("%d
    ",ans);
    89     return 0;
    90 }
  • 相关阅读:
    文件限额
    Shell命令
    HDFS基本概念
    hadoop学习
    CentOS 5.6怎么安装MongoDB数据库?
    RHEL/CentOS 6.x使用EPEL6与remi的yum源安装MySQL 5.5.x
    centos6.x yum 安装 mysql5.6 mysql5.7
    Centos6.4环境下DNS服务器的搭建
    CentOS系统中使用iptables设置端口转发
    通过WEB网管登录
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9575318.html
Copyright © 2011-2022 走看看