Problem Description

Open Source Tools help earthquake researchers stay a step ahead. Many geological research facilities around the world use or are in the process of developing open source software and applications designed to interpret and share information with other researchers. For example, OpenSees is an open source software framework for developing apps that help understand what happens to structures during and after earthquakes to help engineers design stronger buildings. Researchers are also using OpenSees to understand the potential ill-effects of seismic activity on viaducts and bridges.

China has had an earthquake that has struck Sichuan Province on Monday 12 May 2008!

The earthquake has damaged some of the cities so that they are unpassable. Remarkably, after repairing by Chinese People's Liberation Army, all the driveways between cities were fixed.

As usual, Sichuan Province is modeled as a set of P (1 <= P <= 3,000) cities conveniently numbered 1..P which are connected by a set of C (1 <= C <= 20,000) non-directional driveways conveniently numbered 1..C. Driveway i connects city a_i and b_i (1 <= a_i <= P; 1 <= b_i <= P). Driveway might connect a_i to itself or perhaps might connect two cities more than once. The Crisis Center is located in city 1.

A total of N (1 <= N <= P) survivors (in different cities) sequentially contacts Crisis Center via moobile phone with an integer message report_j (2 <= report_j <= P) that indicates that city report_j is undamaged but that the calling survivor is unable to return to the Crisis Center from city report_j because he/she could not find a path that does not go through damaged city.

After all the survivors report in, determine the minimum number of cities that are damaged.

 Input

Input consists of several testcases. The format of each case as follow:

  • Line 1: Three space-separated integers: P, C, and N
  • Lines 2..C+1: Line i+1 describes cowpath i with two integers: a_i and b_i
  • Lines C+2..C+N+1: Line C+1+j contains a single integer: report_j

 Output

For each testcase, output a line with one number, the minimum number of damaged cities.

用最大流最小割定理,最大流=最小割,很久以前做的,题目已忘,我是来放模版的

DINIC算法+当前弧优化+有容量上限,78MS

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. using namespace std;
  5.  
  6. #define MAXN 6010
  7. #define MAXM 100010
  8.  
  9. #define INF 0x7fffffff
  10.  
  11. struct Dinic {
  12. int n, m, st, ed, ecnt;
  13. int vis[MAXN], head[MAXN];
  14. int cur[MAXN], d[MAXN];
  15. int to[MAXM], next[MAXM], flow[MAXM], cap[MAXM];
  16.  
  17. void init(int ss, int tt){
  18. memset(head,,sizeof(head));
  19. ecnt = ;
  20. st = ss; ed = tt;
  21. }
  22.  
  23. void addEdge(int u,int v,int c) {
  24. //flow[ecnt] = c
  25. to[ecnt] = v; cap[ecnt] = c; flow[ecnt] = ; next[ecnt] = head[u]; head[u] = ecnt++;
  26. to[ecnt] = u; cap[ecnt] = ; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
  27. }
  28.  
  29. bool bfs() {
  30. memset(vis, , sizeof(vis));
  31. queue<int> que; que.push(st);
  32. d[st] = ; vis[st] = true;
  33. while(!que.empty()){
  34. int u = que.front(); que.pop();
  35. for(int p = head[u]; p; p = next[p]){
  36. int v = to[p];
  37. if (!vis[v] && cap[p] > flow[p]){//flow[p] > 0
  38. vis[v] = ;
  39. d[v] = d[u] + ;
  40. que.push(v);
  41. if(v == ed) return true;
  42. }
  43. }
  44. }
  45. return vis[ed];
  46. }
  47.  
  48. int dfs(int u, int a) {
  49. if(u == ed || a == ) return a;
  50. int outflow = , f;
  51. for(int &p = cur[u]; p; p = next[p]){
  52. int v = to[p];
  53. if(d[u] + == d[v] && (f = dfs(v, min(a, cap[p] - flow[p]))) > ){//min(a, flow[p])
  54. flow[p] += f;//flow[p] -= f;
  55. flow[p ^ ] -= f;//flow[p ^ 1] += f;
  56. outflow += f;
  57. a -= f;
  58. if(a == ) break;
  59. }
  60. }
  61. return outflow;
  62. }
  63.  
  64. int Maxflow() {
  65. int ans = ;
  66. while(bfs()){
  67. for(int i = ; i <= ed; ++i) cur[i] = head[i];
  68. ans += dfs(st, INF);
  69. }
  70. return ans;
  71. }
  72. } G;
  73.  
  74. int vis[MAXN];
  75.  
  76. int main() {
  77. int ss, tt, N, C, P;
  78. while(scanf("%d%d%d",&P,&C,&N)!=EOF){
  79. ss = ; tt = *P+;
  80. G.init(ss, tt);
  81. while(C--){
  82. int a, b;
  83. scanf("%d%d",&a,&b);
  84. G.addEdge(a + P, b, INF);
  85. G.addEdge(b + P, a, INF);
  86. }
  87. memset(vis, , sizeof(vis));
  88. while(N--){
  89. int x;
  90. scanf("%d",&x);
  91. G.addEdge(x, tt, INF);
  92. vis[x] = ;
  93. }
  94. for(int i = ; i <= P; ++i){
  95. if(i != && !vis[i]) G.addEdge(i, i + P, );
  96. else G.addEdge(i, i + P, INF);
  97. }
  98. G.n = tt;
  99. printf("%d\n",G.Maxflow());
  100. }
  101. return ;
  102. }

DINIC算法+当前弧优化+只有余量,62MS

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. using namespace std;
  5.  
  6. #define MAXN 6010
  7. #define MAXM 100010
  8.  
  9. #define INF 0x7fffffff
  10.  
  11. struct Dinic {
  12. int n, m, st, ed, ecnt;
  13. int vis[MAXN], head[MAXN];
  14. int cur[MAXN], d[MAXN];
  15. int to[MAXM], next[MAXM], flow[MAXM];
  16.  
  17. void init(int ss, int tt){
  18. memset(head,,sizeof(head));
  19. ecnt = ;
  20. st = ss; ed = tt;
  21. }
  22.  
  23. void addEdge(int u,int v,int f) {
  24. to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++;
  25. to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
  26. }
  27.  
  28. bool bfs() {
  29. memset(vis, , sizeof(vis));
  30. queue<int> que; que.push(st);
  31. d[st] = ; vis[st] = true;
  32. while(!que.empty()){
  33. int u = que.front(); que.pop();
  34. for(int p = head[u]; p; p = next[p]){
  35. int v = to[p];
  36. if (!vis[v] && flow[p] > ){
  37. vis[v] = ;
  38. d[v] = d[u] + ;
  39. que.push(v);
  40. if(v == ed) return true;
  41. }
  42. }
  43. }
  44. return vis[ed];
  45. }
  46.  
  47. int dfs(int u, int a) {
  48. if(u == ed || a == ) return a;
  49. int outflow = , f;
  50. for(int &p = cur[u]; p; p = next[p]){
  51. int v = to[p];
  52. if(d[u] + == d[v] && (f = dfs(v, min(a, flow[p]))) > ){
  53. flow[p] -= f;
  54. flow[p ^ ] += f;
  55. outflow += f;
  56. a -= f;
  57. if(a == ) break;
  58. }
  59. }
  60. return outflow;
  61. }
  62.  
  63. int Maxflow() {
  64. int ans = ;
  65. while(bfs()){
  66. for(int i = ; i <= ed; ++i) cur[i] = head[i];
  67. ans += dfs(st, INF);
  68. }
  69. return ans;
  70. }
  71. } G;
  72.  
  73. int vis[MAXN];
  74.  
  75. int main() {
  76. int ss, tt, N, C, P;
  77. while(scanf("%d%d%d",&P,&C,&N)!=EOF){
  78. ss = ; tt = *P+;
  79. G.init(ss, tt);
  80. while(C--){
  81. int a, b;
  82. scanf("%d%d",&a,&b);
  83. G.addEdge(a + P, b, INF);
  84. G.addEdge(b + P, a, INF);
  85. }
  86. memset(vis, , sizeof(vis));
  87. while(N--){
  88. int x;
  89. scanf("%d",&x);
  90. G.addEdge(x, tt, INF);
  91. vis[x] = ;
  92. }
  93. for(int i = ; i <= P; ++i){
  94. if(i != && !vis[i]) G.addEdge(i, i + P, );
  95. else G.addEdge(i, i + P, INF);
  96. }
  97. G.n = tt;
  98. printf("%d\n",G.Maxflow());
  99. }
  100. return ;
  101. }

ISAP算法,78MS(把注释删掉再交一次又变成了93MS,OJ的时间果然信不过o(╯□╰)o)//不能有点0

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <queue>
  5. using namespace std;
  6.  
  7. #define MAXN 6010
  8. #define MAXM 100010
  9. #define INF 0x7fffffff
  10.  
  11. struct SAP {
  12. int vis[MAXN], head[MAXN];
  13. int gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN];
  14. int to[MAXM], flow[MAXM], next[MAXM];
  15. int ecnt, st, ed;
  16.  
  17. void init(int ss, int tt) {
  18. memset(head, , sizeof(head));
  19. ecnt = ;
  20. st = ss; ed = tt;
  21. }
  22.  
  23. void addEdge(int u,int v,int f) {
  24. to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++;
  25. to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
  26. }
  27.  
  28. int Max_flow() {
  29. int ans = , minFlow = INF, n = ed, u;
  30. for (int i = ; i <= n; ++i){
  31. cur[i] = head[i];
  32. gap[i] = dis[i] = ;
  33. }
  34. u = pre[st] = st;
  35. gap[] = n;
  36. while (dis[st] < n){
  37. bool flag = false;
  38. for (int &p = cur[u]; p; p = next[p]){
  39. int v = to[p];
  40. if (flow[p] > && dis[u] == dis[v] + ){
  41. flag = true;
  42. minFlow = min(minFlow, flow[p]);
  43. pre[v] = u;
  44. u = v;
  45. if(u == ed){
  46. ans += minFlow;
  47. while (u != st){
  48. u = pre[u];
  49. flow[cur[u]] -= minFlow;
  50. flow[cur[u] ^ ] += minFlow;
  51. }
  52. minFlow = INF;
  53. }
  54. break;
  55. }
  56. }
  57. if (flag) continue;
  58. int minDis = n-;
  59. for (int p = head[u]; p; p = next[p]){
  60. int v = to[p];
  61. if (flow[p] && dis[v] < minDis){
  62. minDis = dis[v];
  63. cur[u] = p;
  64. }
  65. }
  66. if (--gap[dis[u]] == ) break;
  67. gap[dis[u] = minDis+]++;
  68. u = pre[u];
  69. }
  70. return ans;
  71. }
  72. } G;
  73.  
  74. bool vis[MAXN];
  75.  
  76. int main() {
  77. int ss, tt, N, C, P;
  78. while(scanf("%d%d%d",&P,&C,&N)!=EOF) {
  79. ss = ; tt = *P+;
  80. G.init(ss, tt);
  81. while(C--) {
  82. int a, b;
  83. scanf("%d%d",&a,&b);
  84. G.addEdge(a + P, b, INF);
  85. G.addEdge(b + P, a, INF);
  86. }
  87. memset(vis, , sizeof(vis));
  88. while(N--) {
  89. int x;
  90. scanf("%d",&x);
  91. G.addEdge(x, tt, INF);
  92. vis[x] = ;
  93. }
  94. for(int i = ; i <= P; ++i) {
  95. if(i != && !vis[i]) G.addEdge(i, i + P, );
  96. else G.addEdge(i, i + P, INF);
  97. }
  98. printf("%d\n",G.Max_flow());
  99. }
  100. return ;
  101. }

ISAP算法+BFS初始化,62MS(SGU 438把我这模板跑跪了,现在换掉了>_<)//不能有点0

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <queue>
  5. using namespace std;
  6.  
  7. #define MAXN 6010
  8. #define MAXM 100010
  9. #define INF 0x7fffffff
  10.  
  11. struct SAP {
  12. int head[MAXN];
  13. int gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN];
  14. int to[MAXM], flow[MAXM], next[MAXM];
  15. int ecnt, st, ed, n;
  16.  
  17. void init(int ss, int tt, int nn) {
  18. memset(head, , sizeof(head));
  19. ecnt = ;
  20. st = ss; ed = tt; n = nn;
  21. }
  22.  
  23. void addEdge(int u,int v,int f) {
  24. to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++;
  25. to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
  26. }
  27.  
  28. void bfs() {
  29. memset(dis, 0x3f, sizeof(dis));
  30. queue<int> que; que.push(ed);
  31. dis[ed] = ;
  32. while(!que.empty()) {
  33. int u = que.front(); que.pop();
  34. ++gap[dis[u]];
  35. for(int p = head[u]; p; p = next[p]) {
  36. int v = to[p];
  37. if (dis[v] > ed && flow[p ^ ] > ) {
  38. dis[v] = dis[u] + ;
  39. que.push(v);
  40. }
  41. }
  42. }
  43. }
  44.  
  45. int Max_flow() {
  46. int ans = , minFlow = INF, u;
  47. for (int i = ; i <= n; ++i){
  48. cur[i] = head[i];
  49. gap[i] = dis[i] = ;
  50. }
  51. u = pre[st] = st;
  52. //gap[0] = n;
  53. bfs();
  54. while (dis[st] < n){
  55. bool flag = false;
  56. for (int &p = cur[u]; p; p = next[p]){
  57. int v = to[p];
  58. if (flow[p] > && dis[u] == dis[v] + ){
  59. flag = true;
  60. minFlow = min(minFlow, flow[p]);
  61. pre[v] = u;
  62. u = v;
  63. if(u == ed){
  64. ans += minFlow;
  65. while (u != st){
  66. u = pre[u];
  67. flow[cur[u]] -= minFlow;
  68. flow[cur[u] ^ ] += minFlow;
  69. }
  70. minFlow = INF;
  71. }
  72. break;
  73. }
  74. }
  75. if (flag) continue;
  76. int minDis = n-;
  77. for (int p = head[u]; p; p = next[p]){
  78. int v = to[p];
  79. if (flow[p] && dis[v] < minDis){
  80. minDis = dis[v];
  81. cur[u] = p;
  82. }
  83. }
  84. if (--gap[dis[u]] == ) break;
  85. gap[dis[u] = minDis+]++;
  86. u = pre[u];
  87. }
  88. return ans;
  89. }
  90. } G;
  91.  
  92. bool vis[MAXN];
  93.  
  94. int main() {
  95. int ss, tt, N, C, P;
  96. while(scanf("%d%d%d",&P,&C,&N)!=EOF) {
  97. ss = ; tt = *P+;
  98. G.init(ss, tt, tt);
  99. while(C--) {
  100. int a, b;
  101. scanf("%d%d",&a,&b);
  102. G.addEdge(a + P, b, INF);
  103. G.addEdge(b + P, a, INF);
  104. }
  105. memset(vis, , sizeof(vis));
  106. while(N--) {
  107. int x;
  108. scanf("%d",&x);
  109. G.addEdge(x, tt, INF);
  110. vis[x] = ;
  111. }
  112. for(int i = ; i <= P; ++i) {
  113. if(i != && !vis[i]) G.addEdge(i, i + P, );
  114. else G.addEdge(i, i + P, INF);
  115. }
  116. printf("%d\n",G.Max_flow());
  117. }
  118. return ;
  119. }

FZU 1844 Earthquake Damage(最大流最小割)的更多相关文章

  1. bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害

    1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 Description Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着 ...

  2. hiho 第116周,最大流最小割定理,求最小割集S,T

    小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...

  3. hihocoder 网络流二·最大流最小割定理

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  4. [HihoCoder1378]网络流二·最大流最小割定理

    思路: 根据最大流最小割定理可得最大流与最小割相等,所以可以先跑一遍EdmondsKarp算法.接下来要求的是经过最小割切割后的图中$S$所属的点集.本来的思路是用并查集处理所有前向边构成的残量网络, ...

  5. HDU 1569 方格取数(2)(最大流最小割の最大权独立集)

    Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大.   ...

  6. 【codevs1907】方格取数3(最大流最小割定理)

    网址:http://codevs.cn/problem/1907/ 题意:在一个矩阵里选不相邻的若干个数,使这些数的和最大. 我们可以把它看成一个最小割,答案就是矩阵中的所有数-最小割.先把矩阵按国际 ...

  7. 洛谷 P2932 [USACO09JAN]地震造成的破坏Earthquake Damage

    P2932 [USACO09JAN]地震造成的破坏Earthquake Damage 题目描述 Wisconsin has had an earthquake that has struck Farm ...

  8. 紫书 例题 11-12 UVa 1515 (最大流最小割)

    这道题要分隔草和洞, 然后刘汝佳就想到了"割"(不知道他怎么想的, 反正我没想到) 然后就按照这个思路走, 网络流建模然后求最大流最小割. 分成两部分, S和草连, 洞和T连 外围 ...

  9. HDU-4289-Control(最大流最小割,拆点)

    链接: https://vjudge.net/problem/HDU-4289 题意: You, the head of Department of Security, recently receiv ...

随机推荐

  1. 个人开发者即时到账收款方案 BufPay.com

    BufPay 个人即时到账支付平台 前言 作为独立开发者,一般只有一个人独立奋战,做出了产品需要收款是非常麻烦的,接入支付宝微信支付都需要公司公户,而注册公司.开公户等一系列操作非常麻烦,成本也很高一 ...

  2. 分享一个在js中判断数据是undefined,NaN,null,的技巧

    教大家如何在js中判断一个值是否是undefined,null,NaN,以及如何单独判断 平常开发过程中大家可能遇到一种问题,就是取页面某个值的时候获取不到这个var就是undefined了,如果是数 ...

  3. Qt5应用程序封包

    系统环境:windows10+vs2017+qt5.12 目的:生成.exe可执行文件. 步骤: 1.选择release模式,生成解决方案. 2.打开命令行,cd到生成的可执行文件.exe目录下 3. ...

  4. 消息队列MSMQ的使用

    1.MSMQ安装 控制面板-程序和功能-打开或关闭Windows功能-Microsoft Message Queue(MSMQ)服务器,选中所有,点击确定. 2.消息队列的应用场景(转载自http:/ ...

  5. ThinkPHP5.0框架事务处理操作简单示例

    本文介绍ThinkPHP5.0框架事务处理操作,结合实例形式分析了ThinkPHP5针对删除操作的事务处理相关操作技巧,可以加深对ThinkPHP源码的理解,需要的朋友可以参考下 事务的调用在mysq ...

  6. Java 面试题 百度/参考的答案

    "a=b"和"a.equals(b)"有什么区别? 如果 a 和 b 都是对象,则 a==b 是比较两个对象的引用,只有当 a 和 b 指向的是堆中的同一个对象 ...

  7. 我的Tmux学习笔记

    0. 修改指令前缀 // ~/.tmux.conf ubind C-b set -g prefix C-a 1. 新建会话 tmux tmux new -s session-name // 可以设置会 ...

  8. Spring初始化机制

    一.main的运行入口 ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml ...

  9. openwrt procd启动流程和脚本分析

    Linux内核执行start_kernel函数时会调用kernel_init来启动init进程,流程如下图: graph LR A[start_kernel] -->B(rest_init) B ...

  10. 20145234黄斐《Java程序设计》第三周学习总结

    教材学习内容总结 类与对象 定义:对象,与过程相对. Java中变量有2种类型,一个是基本类型,另一个则是类类型.基本类型在之前学过,本次学习类类型.使用Java撰写程序几乎都是在使用对象,要产生对象 ...