HDU 4289 Control (最大流+拆点)

http://acm.hdu.edu.cn/showproblem.php?pid=4289

题目讲的是有一些恐怖分子要从S市去往D市,要求在一些城市中安排特工,保证一定能够抓住恐怖分子,因为安排特工需要一定的费用,所以希望找出最小的花费。

思路:可以把每个城市,即每个点拆分成进来的点和出去的点,如x点分成x和x+n,两点连接的边权值为x点上安排特工的费用。而如果x和y两点有连线,则连接x+n,y,然后求从S市到达D市的最大流。之所以能这样求,是因为在求最大流的过程中每次所更新的流量是所有边中最小的,这样最小流量的边就是每个点拆分开的两点之间的连线,这样求的过程中对最大流有限制的就是所有点上的花费了。

  1 /*Dinic算法求最大流*/
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<iostream>
  5 #define point_MAX 10000
  6 #define edge_MAX 100000
  7 #define INF_MAX 999999999
  8 using namespace std;
  9 struct EDGE
 10 {
 11     int to;/*指向的点*/
 12     int next;/*指向的下一条邻边*/
 13     int w;/*权值*/
 14 }edge[edge_MAX];
 15 int len;/*边的数量*/
 16 int point[point_MAX];
 17 int Vertex,Edge;
 18 int d[point_MAX];
 19 void init()/*初始化*/
 20 {
 21     len=0;
 22     memset(point,0,sizeof(point));
 23 }
 24 int add_edge(int a,int b,int w)/*添加由a指向b的权值为w的边*/
 25 {
 26     len++;
 27     edge[len].w=w;
 28     edge[len].to=b;
 29     edge[len].next=point[a];
 30     point[a]=len;
 31     return 0;/*无重边,插入*/
 32 }
 33 int bfs(int s)
 34 {
 35     int q[point_MAX],front=0,rear=1,j,t,i;
 36     q[0]=s;
 37     memset(d,-1,sizeof(d));/**/
 38     d[s]=0;
 39     while(front<rear)
 40     {
 41        t=q[front++];
 42          for(j=point[t];j;j=edge[j].next)
 43          {
 44             if(d[edge[j].to]==-1&&edge[j].w>0)
 45             {
 46              d[edge[j].to]=d[t]+1;
 47            q[rear++]=edge[j].to;/*逐层增加*/
 48         }
 49          }
 50     }
 51     if(d[Vertex]>=0)
 52        return 1;
 53     return 0;
 54 }
 55 long long min(long long a,long long b)
 56 {
 57     return a<b?a:b;
 58 }
 59 long long dinic(int t,long long sum)/*寻找增广路*/
 60 {
 61     int i,os,j;
 62     long long a;
 63     if(t==Vertex)/*如果已经找到汇点,返回sum*/
 64       return sum;
 65     os=sum;
 66     for(i=point[t];i&&sum;i=edge[i].next)
 67     {
 68        if(d[edge[i].to]==d[t]+1&&edge[i].w>0)/*可行流,即增广路*/
 69        {
 70            a=dinic(edge[i].to,min(sum,edge[i].w));
 71            edge[i].w-=a;
 72            for(j=point[edge[i].to];edge[j].to!=t;j=edge[j].next);
 73            edge[j].w+=a;/*处理反向边*/
 74            sum-=a;
 75        }
 76     }
 77     return os-sum;
 78 }
 79 long long DINIC(int s)/*DINIC算法*/
 80 {
 81      long long ans=0;
 82      while(bfs(s))/*遍历整个图,判断是否已经完成最大流*/
 83        ans+=dinic(s,INF_MAX);/*添加所能增加的流量*/
 84      return ans;
 85 }
 86
 87 int main()
 88 {
 89      int i,j,x,y,w,S,D;
 90      int cost[205];
 91      while(scanf("%d%d",&Vertex,&Edge)!=EOF)
 92      {
 93         init();
 94         memset(cost,0,sizeof(cost));
 95         scanf("%d%d",&S,&D);
 96         for(i=1;i<=Vertex;i++)
 97         {
 98             scanf("%d",&cost[i]);
 99             add_edge(i,i+Vertex,cost[i]);
100             add_edge(i+Vertex,i,0);
101         }
102         for(i=0;i<Edge;i++)
103         {
104            scanf("%d%d",&x,&y);
105            add_edge(x+Vertex,y,INF_MAX);
106            add_edge(y,x+Vertex,0);
107            add_edge(y+Vertex,x,INF_MAX);/*添加反向边*/
108            add_edge(x,y+Vertex,0);
109         }
110         Vertex=D+Vertex;
111         //cout<<"=="<<endl;
112         printf("%lld\n",DINIC(S));/*以S为源点,Vertex为汇点*/
113      }
114      return 0;
115 }

HDU 4289 Control (最大流+拆点)

时间: 2024-10-14 23:13:45

HDU 4289 Control (最大流+拆点)的相关文章

hdu 4289 Control(网络流 最大流+拆点)(模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1545    Accepted Submission(s): 677 Problem Description You, the head of Department o

hdu 4289 Control (最大流)

hdu 4289 Control You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to another one (the destination). You know their date, sour

HDU 4289 Control (网络流-最小割)

Control Problem Description You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to another one (the destination). You know their

hdu 4289 利用最大流思想求图的最小割

http://acm.hdu.edu.cn/showproblem.php?pid=4289 Problem Description You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to anothe

POJ 3422 HDU 2686,3376 费用流拆点建图

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3376 http://acm.hdu.edu.cn/showproblem.php?pid=2686 http://poj.org/problem?id=3422 POJ 3422为从矩阵左上角走到右下角,最多走k次,每个格子里的数字只能算一次,后面可以重复经过,求经过的各个数字的和的最大值. 拆点,入点向出点连流量为1,费用为当前格子负值的边,向下方,右方连边,流量为k,费用为0,起点连流量为1,

hdu 4292 Food 最大流+拆点

Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2664    Accepted Submission(s): 899 Problem Description You, a part-time dining service worker in your college's dining hall, are now confus

hdu 4289 Control(最小割 + 拆点)

http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2247    Accepted Submission(s): 940 Problem Description You, the head of Department of Secu

HDU 4289 Control (最小割 拆点)

Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 904 Problem Description You, the head of Department of Security, recently received a top-secret informati

I - Control - HDU 4289 (最大流)

题意:有N个城市,现在城市S出现了一伙歹徒,他们想运送一些炸弹到D城市,不过警方已经得到了线报知道他们的事情,不过警察不知道他们所在的具体位置,所以只能采取封锁城市的办法来阻断暴徒,不过封锁城市是需要花费一定代价的,由于警局资金比较紧张,所以想知道如果完全阻断暴徒从S城市到达D城市的最小需要花费的代价. 输入: 首先输入的是N,M表示有N个城市M条道路,接下来有N行每行一个数字表示封锁这个城市的代价,然后M行道路,每个道路都连接两个城市(路没有交叉,并且是双向路). 分析:这应该叫做最小割,有向