链接:

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

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82835#problem/I

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

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<queue>
  6. using namespace std;
  7.  
  8. #define N 510
  9. #define INF 0x3fffffff
  10.  
  11. struct node {int v, flow, next;} a[N*N];
  12.  
  13. int G[N][N], g[N][N], Layer[N], Head[N], cnt, n, m;
  14.  
  15. void Init()
  16. {
  17. cnt = ;
  18. memset(Head, -, sizeof(Head));
  19. }
  20.  
  21. void Add(int u, int v, int flow)
  22. {
  23. a[cnt].v = v;
  24. a[cnt].flow = flow;
  25. a[cnt].next = Head[u];
  26. Head[u] = cnt++;
  27.  
  28. swap(u, v);
  29.  
  30. a[cnt].v = v;
  31. a[cnt].flow = ;
  32. a[cnt].next = Head[u];
  33. Head[u] = cnt++;
  34. }
  35.  
  36. bool BFS(int Start, int End)
  37. {
  38. queue<int>Q;
  39. Q.push(Start);
  40.  
  41. memset(Layer, , sizeof(Layer));
  42. Layer[Start] = ;
  43.  
  44. while(Q.size())
  45. {
  46. int u = Q.front(); Q.pop();
  47.  
  48. if(u==End) return true;
  49.  
  50. for(int i=Head[u]; i!=-; i=a[i].next)
  51. {
  52. int v = a[i].v;
  53.  
  54. if(!Layer[v] && a[i].flow)
  55. {
  56. Layer[v] = Layer[u] + ;
  57. Q.push(v);
  58. }
  59. }
  60. }
  61. return false;
  62. }
  63. int DFS(int u, int MaxFlow, int End)
  64. {
  65. if(u==End) return MaxFlow;
  66.  
  67. int uflow=;
  68.  
  69. for(int i=Head[u]; i!=-; i=a[i].next)
  70. {
  71. int v = a[i].v;
  72. if(Layer[v]==Layer[u]+ && a[i].flow)
  73. {
  74. int flow = min(a[i].flow, MaxFlow-uflow);
  75. flow = DFS(v, flow, End);
  76.  
  77. a[i].flow -= flow;
  78. a[i^].flow += flow;
  79. uflow += flow;
  80.  
  81. if(uflow==MaxFlow) break;
  82. }
  83. }
  84.  
  85. if(uflow==) Layer[u] = ;
  86.  
  87. return uflow;
  88. }
  89. int Dinic(int Start, int End)
  90. {
  91. int MaxFlow=;
  92.  
  93. while(BFS(Start, End)==true)
  94. MaxFlow += DFS(Start, INF, End);
  95.  
  96. return MaxFlow;
  97. }
  98.  
  99. int main()
  100. {
  101. while(scanf("%d%d", &n, &m)!=EOF)
  102. {
  103. int Start, End, i, flow, u, v;
  104.  
  105. scanf("%d%d", &Start, &End);
  106.  
  107. Init();
  108. for(i=; i<=n; i++)
  109. {
  110. scanf("%d", &flow);
  111. Add(i, i+n, flow);
  112. }
  113.  
  114. for(i=; i<=m; i++)
  115. {
  116. scanf("%d%d", &u, &v);
  117. Add(u+n, v, INF);
  118. Add(v+n, u, INF);
  119. }
  120.  
  121. printf("%d\n", Dinic(Start, End+n));
  122. }
  123. return ;
  124. }

粘大神的代码,其实不懂SAP,先借鉴一下,等等在研究

SAP:

  1. const int MAXN=;//点数的最大值
  2. const int MAXM=;//边数的最大值
  3. const int INF=0x3f3f3f3f;
  4.  
  5. struct Node
  6. {
  7. int from,to,next;
  8. int cap;
  9. }edge[MAXM];
  10. int tol;
  11. int head[MAXN];
  12. int dep[MAXN];
  13. int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
  14.  
  15. int n;//n是总的点的个数,包括源点和汇点
  16.  
  17. void init()
  18. {
  19. tol=;
  20. memset(head,-,sizeof(head));
  21. }
  22.  
  23. void addedge(int u,int v,int w)
  24. {
  25. edge[tol].from=u;
  26. edge[tol].to=v;
  27. edge[tol].cap=w;
  28. edge[tol].next=head[u];
  29. head[u]=tol++;
  30. edge[tol].from=v;
  31. edge[tol].to=u;
  32. edge[tol].cap=;
  33. edge[tol].next=head[v];
  34. head[v]=tol++;
  35. }
  36. void BFS(int start,int end)
  37. {
  38. memset(dep,-,sizeof(dep));
  39. memset(gap,,sizeof(gap));
  40. gap[]=;
  41. int que[MAXN];
  42. int front,rear;
  43. front=rear=;
  44. dep[end]=;
  45. que[rear++]=end;
  46. while(front!=rear)
  47. {
  48. int u=que[front++];
  49. if(front==MAXN)front=;
  50. for(int i=head[u];i!=-;i=edge[i].next)
  51. {
  52. int v=edge[i].to;
  53. if(dep[v]!=-)continue;
  54. que[rear++]=v;
  55. if(rear==MAXN)rear=;
  56. dep[v]=dep[u]+;
  57. ++gap[dep[v]];
  58. }
  59. }
  60. }
  61. int SAP(int start,int end)
  62. {
  63. int res=;
  64. BFS(start,end);
  65. int cur[MAXN];
  66. int S[MAXN];
  67. int top=;
  68. memcpy(cur,head,sizeof(head));
  69. int u=start;
  70. int i;
  71. while(dep[start]<n)
  72. {
  73. if(u==end)
  74. {
  75. int temp=INF;
  76. int inser;
  77. for(i=;i<top;i++)
  78. if(temp>edge[S[i]].cap)
  79. {
  80. temp=edge[S[i]].cap;
  81. inser=i;
  82. }
  83. for(i=;i<top;i++)
  84. {
  85. edge[S[i]].cap-=temp;
  86. edge[S[i]^].cap+=temp;
  87. }
  88. res+=temp;
  89. top=inser;
  90. u=edge[S[top]].from;
  91. }
  92. if(u!=end&&gap[dep[u]-]==)//出现断层,无增广路
  93. break;
  94. for(i=cur[u];i!=-;i=edge[i].next)
  95. if(edge[i].cap!=&&dep[u]==dep[edge[i].to]+)
  96. break;
  97. if(i!=-)
  98. {
  99. cur[u]=i;
  100. S[top++]=i;
  101. u=edge[i].to;
  102. }
  103. else
  104. {
  105. int min=n;
  106. for(i=head[u];i!=-;i=edge[i].next)
  107. {
  108. if(edge[i].cap==)continue;
  109. if(min>dep[edge[i].to])
  110. {
  111. min=dep[edge[i].to];
  112. cur[u]=i;
  113. }
  114. }
  115. --gap[dep[u]];
  116. dep[u]=min+;
  117. ++gap[dep[u]];
  118. if(u!=start)u=edge[S[--top]].from;
  119. }
  120. }
  121. return res;
  122. }

(网络流 最大流 Dinic || SAP)Control -- hdu --4289的更多相关文章

  1. [讲解]网络流最大流dinic算法

    网络流最大流算法dinic ps:本文章不适合萌新,我写这个主要是为了复习一些细节,概念介绍比较模糊,建议多刷题去理解 例题:codevs草地排水,方格取数 [抒情一下] 虽然老师说这个多半不考,但是 ...

  2. I - Control - HDU 4289 (最大流)

    题意:有N个城市,现在城市S出现了一伙歹徒,他们想运送一些炸弹到D城市,不过警方已经得到了线报知道他们的事情,不过警察不知道他们所在的具体位置,所以只能采取封锁城市的办法来阻断暴徒,不过封锁城市是需要 ...

  3. Power Network(网络流最大流 & dinic算法 + 优化)

    Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 24019   Accepted: 12540 D ...

  4. 网络流最大流——dinic算法

    前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问 ...

  5. 最大流 Dinic + Sap 模板

    不说别的,直接上模板. Dinic+当前弧优化: struct Edge{ int x,y,c,ne; }e[M*]; int be[N],all; int d[N],q[N]; int stack[ ...

  6. 网络流--最大流dinic模板

    标准的大白书式模板,除了变量名并不一样……在主函数中只需要用到 init 函数.add 函数以及 mf 函数 #include<stdio.h> //差不多要加这么些头文件 #includ ...

  7. UESTC 1143 数据传输 网络流 最大流 Dinic

    数据传输 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  Sta ...

  8. 网络流最大流dinic

    hdu 6214 #include <bits/stdc++.h> #include<cstdio> #include<cstring> #include<q ...

  9. 【uva 11082】Matrix Decompressing(图论--网络流最大流 Dinic+拆点二分图匹配)

    题意:有一个N行M列的正整数矩阵,输入N个前1~N行所有元素之和,以及M个前1~M列所有元素之和.要求找一个满足这些条件,并且矩阵中的元素都是1~20之间的正整数的矩阵.输入保证有解,而且1≤N,M≤ ...

随机推荐

  1. vim跳转到指定行

    第一种方法 在编辑模式下(非输入模式)下输入ngg 或者 nGn为指定的行数(如25)25gg或者25G 跳转到第25行. 25gg 第二种方法 在命令模式下输入行号n : n 查看当然光标所在的行和 ...

  2. 输入N组父子对,求父子对所组成的二叉树的高度----17年某公司的笔试题

    题目的大致意思如下: 输入N组数,一组数代表一个父子对(如,0 1,0代表父节点,1代表子节点),求这N组数所组成的二叉树的高度: 例如: 输入:6  0 1  0 2  1 3  1 4  2 5 ...

  3. 在windows 2008 R2中SQl Server 2008中代理启动失败的一个原因总结

    启动SQL代理的时候报错如下: 关调用实时(JIT)调试而不是此对话框的详细信息,请参见此消息的结尾. ************** 异常文本 **************System.NullRef ...

  4. 吴裕雄 数据挖掘与分析案例实战(10)——KNN模型的应用

    # 导入第三方包import pandas as pd # 导入数据Knowledge = pd.read_excel(r'F:\\python_Data_analysis_and_mining\\1 ...

  5. Ubuntu 安装 Zabbix 3.2详细步骤

    创建 zabbix 用户 因为zabbix 程序的守护进程需要非特权用户,所以需要创建一个 zabbix 用户,即使从 root 用户启动 zabbix 程序,也会自动切换到 zabbix 用户,所以 ...

  6. VScode 安装必备

    1.运行程序:

  7. blast及其格式输出简介

    1)blast产生背景 双序列比对可以采用是基于动态规划算法的Needleman-Wunsch(NW)和Smith-Waterman algorithm(SW)算法,虽然精度高,但计算消耗大.当与数据 ...

  8. test5

    ## 前言 因为vs2010没有集成mvvmlight 所以想要使用mvvmlight的relaycomman需要引用dll 需要测试某个功能的时候,不能进行快带的集成 ## 引用mvvmlight ...

  9. 第六章 图(d)深度优先搜索

  10. 第十章 泛型程序设计与C++标准模板库 泛型程序设计及STL的结构