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

    1834: [ZJOI2010]network 网络扩容

    Time Limit: 3 Sec  Memory Limit: 64 MB
    Submit: 2701  Solved: 1368
    [Submit][Status][Discuss]

    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
     
     
     
    【题解】
    网络流和费用流的结合。
    第一问很简单,直接跑一遍dinic即可。
    第二问是费用流,将原图上的每条边上建立一条附属边,流量为k,费用为扩容费用,然后跑费用流即可。
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<ctime>
      7 #include<algorithm>
      8 #include<queue>
      9 using namespace std;
     10 #define INF 1000000000
     11 #define MAXN 5010
     12 struct node{int x,y,next,v,c,rel;}e[MAXN*10],edge[MAXN*10];
     13 int n,m,k,len,ans,Link[MAXN],level[MAXN],vis[MAXN],dis[MAXN],lastnode[MAXN],lastedge[MAXN],q[MAXN*10];
     14 inline int read()
     15 {
     16     int x=0,f=1;  char ch=getchar();
     17     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
     18     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
     19     return x*f;
     20 }
     21 void insert(int x,int y,int v,int c)
     22 {
     23     e[++len].next=Link[x];Link[x]=len;e[len].x=x;e[len].y=y;e[len].v=v;e[len].c=c;e[len].rel=len+1;
     24     e[++len].next=Link[y];Link[y]=len;e[len].x=y;e[len].y=x;e[len].v=0;e[len].c=-c;e[len].rel=len-1;
     25 }
     26 bool bfs()
     27 {
     28     memset(level,-1,sizeof(level));
     29     int head=0,tail=1;  q[1]=1;  level[1]=0;
     30     while(++head<=tail)
     31         for(int i=Link[q[head]];i;i=e[i].next)
     32             if(level[e[i].y]<0&&e[i].v)
     33             {
     34                 q[++tail]=e[i].y;
     35                 level[q[tail]]=level[q[head]]+1;
     36             }
     37     return level[n]>=0;
     38 }
     39 int dinic(int x,int flow)
     40 {
     41     if(x==n) return flow;
     42     int maxflow=0,d=0;
     43     for(int i=Link[x];i&&maxflow<flow;i=e[i].next)
     44         if(level[e[i].y]==level[x]+1&&e[i].v)
     45             if(d=dinic(e[i].y,min(e[i].v,flow-maxflow)))
     46             {
     47                 maxflow+=d;
     48                 e[i].v-=d;
     49                 e[e[i].rel].v+=d;
     50             }
     51     if(!maxflow)  level[x]=-1;
     52     return maxflow;
     53 }
     54 void solve1()
     55 {
     56     int d=0;
     57     ans=0;
     58     while(bfs())
     59         while(d=dinic(1,INF))
     60             ans+=d;
     61     printf("%d ",ans);
     62 }
     63 bool spfa()
     64 {
     65     memset(vis,0,sizeof(vis));
     66     memset(dis,10,sizeof(dis));
     67     int head=0,tail=1,oo=dis[0];
     68     q[1]=1;  vis[1]=1;  dis[1]=0;
     69     while(++head<=tail)
     70     {
     71         int x=q[head];
     72         for(int i=Link[x];i;i=e[i].next)
     73             if(dis[x]+e[i].c<dis[e[i].y]&&e[i].v)
     74             {
     75                 dis[e[i].y]=dis[x]+e[i].c;
     76                 if(!vis[e[i].y])
     77                 {
     78                     q[++tail]=e[i].y;
     79                     vis[e[i].y]=1;
     80                 }
     81                 lastnode[e[i].y]=x;  lastedge[e[i].y]=i;
     82             }
     83         vis[x]=0;
     84     }
     85     return dis[n]<oo;
     86 }
     87 void cost()
     88 {
     89     int d=k;
     90     for(int i=n;i!=1;i=lastnode[i])
     91         if(e[lastedge[i]].v<d)
     92             d=e[lastedge[i]].v;
     93     for(int i=n;i!=1;i=lastnode[i])
     94     {
     95         int j=lastedge[i];
     96         e[j].v-=d;
     97         e[e[j].rel].v+=d;
     98         ans+=d*e[j].c;
     99     }
    100     k-=d;
    101 }
    102 void solve2()
    103 {
    104     ans=0;
    105     while(k)//控制1点的流量,相当于一个超级源的作用
    106     {
    107         spfa();
    108         cost();
    109     }
    110     printf("%d
    ",ans);
    111 }
    112 int main()
    113 {
    114     freopen("cin.in","r",stdin);
    115     freopen("cout.out","w",stdout);
    116     n=read();  m=read();  k=read();
    117     for(int i=1;i<=m;i++)
    118     {
    119         int x=read(),y=read(),v=read(),c=read();
    120         insert(x,y,v,0);
    121         edge[i].x=x; edge[i].y=y; edge[i].c=c;
    122     }
    123     solve1();
    124     for(int i=1;i<=m;i++)  insert(edge[i].x,edge[i].y,k,edge[i].c);
    125     solve2();
    126     return 0;
    127 }
  • 相关阅读:
    windows下安装mysql 开机启动
    android基础---->XMl数据的解析
    web基础---->session的使用
    android基础---->ListView的使用
    android基础---->WebView的使用
    android基础---->Toast的使用
    android基础---->SQLite数据库的使用
    android基础---->SharedPreferences的使用
    js数组的操作
    Javascript中的Array(数组) 、{}(映射) 与JSON解析
  • 原文地址:https://www.cnblogs.com/chty/p/5946545.html
Copyright © 2011-2022 走看看