zoukankan      html  css  js  c++  java
  • 【BZOJ 1834】 [ZJOI2010]network 网络扩容

    Description

    给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。

    Input

    输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。

    Output

    输出文件一行包含两个整数,分别表示问题1和问题2的答案。

    Sample Input

    5 8 2
    1 2 5 8
    2 5 9 9
    5 1 6 2
    5 1 1 8
    1 2 8 7
    2 5 4 9
    1 2 1 1
    1 4 2 1

    Sample Output

    13 19
    30%的数据中,N<=100
    100%的数据中,N<=1000,M<=5000,K<=10
     
    第一问最大流
    第二问
    建立超级源和超级汇,超级源向1连边,容量为K,n向超级汇连边,容量同上。原来的每条边再建立一条,容量为inf,费用为W,在原图上增广,跑最小费用最大流
    但是!!!新边一定要在求完第一问之后再建。。。
    代码量略大。。。不过我都上套板子。。。
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<iostream>
      5 using namespace std;
      6 const int N=55555,inf=1000000;
      7 struct ee{int to,next,f,w;}e[N*2];
      8 int S,T,cnt=1,n,k,ans1,ans2,timer,m,u[N],v[N],w[N],c[N],mid;
      9 int head[N],dis[N],pre[N],q[N];
     10 bool inq[N],flag=1;
     11 void ins(int u,int v,int f,int w){
     12     e[++cnt].to=v,e[cnt].next=head[u],e[cnt].f=f,e[cnt].w=w,head[u]=cnt;
     13     e[++cnt].to=u,e[cnt].next=head[v],e[cnt].f=0,e[cnt].w=-w,head[v]=cnt;
     14 }
     15 bool spfa(){
     16     for (int i=1;i<=T;i++) dis[i]=inf;
     17     int h=0,t=1;
     18     q[t]=S;dis[S]=0;inq[S]=1;
     19     while (h!=t){
     20         int now=q[++h];if(h==2501) h=0;
     21         for (int i=head[now];i;i=e[i].next){
     22             int v=e[i].to;
     23             if (dis[v]>dis[now]+e[i].w&&e[i].f){
     24                 dis[v]=dis[now]+e[i].w;
     25                 pre[v]=i;
     26                 if (!inq[v]){
     27                     q[++t]=v;if (t==2501) t=0;
     28                     inq[v]=1;
     29                 }
     30             }
     31         }
     32         inq[now]=0;
     33     }
     34     if (dis[T]==inf) return 0;
     35     return 1;
     36 }
     37   
     38 void updata(){
     39     int tmp=T,flow=inf;
     40     while (tmp!=S){
     41         int l=pre[tmp],v=e[l].to;
     42         flow=min(flow,e[l].f);
     43         tmp=e[l^1].to;
     44     }
     45     tmp=T;
     46     while (tmp!=S){
     47         int l=pre[tmp],v=e[l].to;
     48         e[l].f-=flow;e[l^1].f+=flow;
     49         tmp=e[l^1].to;
     50     }
     51     mid+=flow;
     52     if(mid>=k) flag=0;
     53     ans2+=dis[T]*flow;
     54 }
     55  
     56 bool bfs(){
     57     for (int i=1;i<=T;i++) dis[i]=inf;
     58     int h=0,t=1,now;
     59     q[1]=1;dis[1]=0;
     60     while(h!=t){
     61         now=q[++h];
     62         for (int i=head[now];i;i=e[i].next){
     63             int v=e[i].to;
     64             if (e[i].f&&dis[now]+1<dis[v]){
     65                 dis[v]=dis[now]+1;
     66                 if (v==n)return 1;
     67                 q[++t]=v;
     68             }
     69         }
     70     }
     71     if (dis[n]==inf) return 0; return 1;
     72 }
     73   
     74 int dinic(int now,int f){
     75     if (now==n) return f;
     76     int rest=f;
     77     for (int i=head[now];i;i=e[i].next){
     78         int v=e[i].to;
     79         if (e[i].f&&dis[v]==dis[now]+1&&rest){
     80             int t=dinic(v,min(rest,e[i].f));
     81             if (!t) dis[v]=0;
     82             e[i].f-=t;
     83             e[i^1].f+=t;
     84             rest-=t;
     85             //if(t) printf("%d %d %d
    ",now,v,e[i].f);
     86         }
     87     }
     88     return f-rest;
     89 }
     90  
     91 int main(){
     92     scanf("%d%d%d",&n,&m,&k);
     93     S=0,T=n+1;
     94     for (int i=1;i<=m;i++){
     95         scanf("%d%d%d%d",&u[i],&v[i],&c[i],&w[i]);
     96         ins(u[i],v[i],c[i],0);
     97     }
     98     ins(S,1,k,0);ins(n,T,k,0);
     99     while(bfs()) 
    100     ans1+=dinic(1,inf);
    101     for (int i=1;i<=m;i++)ins(u[i],v[i],inf,w[i]);
    102     while(flag&&spfa()) 
    103     updata();
    104     printf("%d %d",ans1,ans2);
    105 }
  • 相关阅读:
    关于前期开发
    unity3d-知识汇总
    unity3d 第一人称脚本解释:MouseLook
    unity3d-游戏实战突出重围,整合游戏
    unity3d-游戏实战突出重围,第四天 添加角色
    unity3d-游戏实战突出重围,第三天 绘制数字
    unity3d-游戏实战突出重围,第二天 制作血条
    unity3d-游戏实战突出重围,第一天
    unity3d-解密加密数据
    unity3d-代码控制游戏角色控制器移动
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5189855.html
Copyright © 2011-2022 走看看