2502: 清理雪道

Time Limit: 10 Sec  Memory Limit: 128 MB

Description

       滑雪场坐落在FJ省西北部的若干座山上。
从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向。
你的团队负责每周定时清理雪道。你们拥有一架直升飞机,每次飞行可以从总部带一个人降落到滑雪场的某个地点,然后再飞回总部。从降落的地点出发,这个人可以顺着斜坡向下滑行,并清理他所经过的雪道。
由于每次飞行的耗费是固定的,为了最小化耗费,你想知道如何用最少的飞行次数才能完成清理雪道的任务。
 

Input

 

输入文件的第一行包含一个整数n (2 <= n <= 100) – 代表滑雪场的地点的数量。接下来的n行,描述1~n号地点出发的斜坡,第i行的第一个数为mi (0 <= mi < n) ,后面共有mi个整数,由空格隔开,每个整数aij互不相同,代表从地点i下降到地点aij的斜坡。每个地点至少有一个斜坡与之相连。

Output

 
       输出文件的第一行是一个整数k – 直升飞机的最少飞行次数。
 

Sample Input

8
1 3
1 7
2 4 5
1 8
1 8
0
2 6 5
0

Sample Output

4
 
下界为1,上界为inf
法一、从超级源点向超级汇点跑一遍dinic,再由普通汇点向普通源点连一条下界为0,上界为inf的边,再由超级源点向超级汇点跑一遍dinic
答案为最后加的那条边的反向边的流量
  1. #include<cstdio>
  2. #include<queue>
  3. #include<algorithm>
  4. #define N 105
  5. #define M 40001
  6. using namespace std;
  7. const int inf=2e9;
  8. int n,a[N],ans;
  9. int src,dec,S,T;
  10. int to[M],next[M],front[N],tot=,cap[M];
  11. int lev[N],cur[N];
  12. queue<int>q;
  13. void add(int u,int v,int w)
  14. {
  15. to[++tot]=v; next[tot]=front[u]; front[u]=tot; cap[tot]=w;
  16. to[++tot]=u; next[tot]=front[v]; front[v]=tot; cap[tot]=;
  17. }
  18. bool bfs(int s,int t)
  19. {
  20. for(int i=;i<=n+;i++) cur[i]=front[i],lev[i]=-;
  21. while(!q.empty()) q.pop();
  22. lev[s]=;
  23. q.push(s);
  24. int now;
  25. while(!q.empty())
  26. {
  27. now=q.front(); q.pop();
  28. for(int i=front[now];i;i=next[i])
  29. if(cap[i]>&&lev[to[i]]==-)
  30. {
  31. lev[to[i]]=lev[now]+;
  32. if(to[i]==t) return true;
  33. q.push(to[i]);
  34. }
  35. }
  36. return false;
  37. }
  38. int dfs(int now,int t,int flow)
  39. {
  40. if(now==t) return flow;
  41. int rest=,delta;
  42. for(int i=front[now];i;i=next[i])
  43. if(cap[i]>&&lev[to[i]]>lev[now])
  44. {
  45. delta=dfs(to[i],t,min(flow-rest,cap[i]));
  46. if(delta)
  47. {
  48. cap[i]-=delta; cap[i^]+=delta;
  49. rest+=delta; if(rest==flow) return rest;
  50. }
  51. }
  52. if(rest!=flow) lev[now]=-;
  53. return rest;
  54. }
  55. int dinic(int s,int t)
  56. {
  57. while(bfs(s,t)) dfs(s,t,inf);
  58. }
  59. int main()
  60. {
  61. scanf("%d",&n);
  62. dec=n+; S=n+;T=n+;
  63. for(int i=;i<=n;i++) add(i,dec,inf);
  64. for(int i=;i<=n;i++) add(src,i,inf);
  65. int x,y;
  66. for(int i=;i<=n;i++)
  67. {
  68. scanf("%d",&x);
  69. while(x--)
  70. {
  71. scanf("%d",&y);
  72. add(i,y,inf);
  73. a[y]++; a[i]--;
  74. }
  75. }
  76. for(int i=;i<=n;i++)
  77. if(a[i]>) add(S,i,a[i]);
  78. else if(a[i]<) add(i,T,-a[i]);
  79. dinic(S,T);
  80. add(dec,src,inf);
  81. dinic(S,T);
  82. printf("%d",cap[tot]);
  83. }

法二、先由普通汇点向普通源点连一条下界为0,上界为inf的边,再由超级源点向超级汇点跑一遍dinic,记那条边的流量为okflow

删去那条边,删去超级源点,删去超级汇点,由普通汇点向普通源点跑一遍dinic,得出最大流为a,

答案为okflow-a

  1. #include<cstdio>
  2. #include<queue>
  3. #include<algorithm>
  4. #define N 105
  5. #define M 40001
  6. using namespace std;
  7. const int inf=2e9;
  8. int n,a[N],ans;
  9. int src,dec,S,T;
  10. int to[M],next[M],front[N],tot=,cap[M];
  11. int lev[N],cur[N];
  12. queue<int>q;
  13. void add(int u,int v,int w)
  14. {
  15. to[++tot]=v; next[tot]=front[u]; front[u]=tot; cap[tot]=w;
  16. to[++tot]=u; next[tot]=front[v]; front[v]=tot; cap[tot]=;
  17. }
  18. bool bfs(int s,int t)
  19. {
  20. for(int i=;i<=n+;i++) cur[i]=front[i],lev[i]=-;
  21. while(!q.empty()) q.pop();
  22. lev[s]=;
  23. q.push(s);
  24. int now;
  25. while(!q.empty())
  26. {
  27. now=q.front(); q.pop();
  28. for(int i=front[now];i;i=next[i])
  29. if(cap[i]>&&lev[to[i]]==-)
  30. {
  31. lev[to[i]]=lev[now]+;
  32. if(to[i]==t) return true;
  33. q.push(to[i]);
  34. }
  35. }
  36. return false;
  37. }
  38. int dfs(int now,int t,int flow)
  39. {
  40. if(now==t) return flow;
  41. int rest=,delta;
  42. for(int i=front[now];i;i=next[i])
  43. if(cap[i]>&&lev[to[i]]>lev[now])
  44. {
  45. delta=dfs(to[i],t,min(flow-rest,cap[i]));
  46. if(delta)
  47. {
  48. cap[i]-=delta; cap[i^]+=delta;
  49. rest+=delta; if(rest==flow) return rest;
  50. }
  51. }
  52. if(rest!=flow) lev[now]=-;
  53. return rest;
  54. }
  55. int dinic(int s,int t)
  56. {
  57. int tmp=;
  58. while(bfs(s,t))
  59. tmp+=dfs(s,t,inf);
  60. return tmp;
  61. }
  62. void del(int x)
  63. {
  64. for(int i=front[x];i;i=next[i])
  65. cap[i]=cap[i^]=;
  66. }
  67. int main()
  68. {
  69. scanf("%d",&n);
  70. dec=n+; S=n+;T=n+;
  71. for(int i=;i<=n;i++) add(i,dec,inf);
  72. for(int i=;i<=n;i++) add(src,i,inf);
  73. int x,y;
  74. for(int i=;i<=n;i++)
  75. {
  76. scanf("%d",&x);
  77. while(x--)
  78. {
  79. scanf("%d",&y);
  80. add(i,y,inf);
  81. a[y]++; a[i]--;
  82. }
  83. }
  84. for(int i=;i<=n;i++)
  85. if(a[i]>) add(S,i,a[i]);
  86. else if(a[i]<) add(i,T,-a[i]);
  87. add(dec,src,inf);
  88. dinic(S,T);
  89. int okflow=cap[tot];
  90. del(T); del(S); cap[tot]=cap[tot-]=;
  91. printf("%d",okflow-dinic(dec,src));
  92. }

bzoj 2502 清理雪道 (有源汇上下界最小流)的更多相关文章

  1. BZOJ 2502 清理雪道/ Luogu P4843 清理雪道 (有源汇上下界最小流)

    题意 有一个有向无环图,求最少的路径条数覆盖所有的边 分析 有源汇上下界最小流板题,直接放代码了,不会的看dalao博客:liu_runda 有点长,讲的很好,静心看一定能看懂 CODE #inclu ...

  2. BZOJ 2502 清理雪道(有源汇上下界最小流)

    题面 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机, ...

  3. BZOJ_2502_清理雪道_有源汇上下界最小流

    BZOJ_2502_清理雪道_有源汇上下界最小流 Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...

  4. 【Loj117】有源汇上下界最小流(网络流)

    [Loj117]有源汇上下界最小流(网络流) 题面 Loj 题解 还是模板题. #include<iostream> #include<cstdio> #include< ...

  5. hdu3157有源汇上下界最小流

    题意:有源汇上下界最小流裸题,主要就是输入要用字符串的问题 #include<bits/stdc++.h> #define fi first #define se second #defi ...

  6. sgu176 有源汇上下界最小流

    题意:有一堆点和边,1起点,n终点,某些边有可能必须满流,要求满足条件的最小流 解法:按原图建边,满流的即上下界都是容量,但是这样按有源汇上下界可行流求出来的可能不是最小流,那么我们需要开始建边的时候 ...

  7. HDU 3157 Crazy Circuits (有源汇上下界最小流)

    题意:一个电路板,上面有N个接线柱(标号1~N)   还有两个电源接线柱  +  - 然后是 给出M个部件正负极的接线柱和最小电流,求一个可以让所有部件正常工作的总电流. 析:这是一个有源汇有上下界的 ...

  8. SGU 176 Flow construction(有源汇上下界最小流)

    Description 176. Flow construction time limit per test: 1 sec. memory limit per test: 4096 KB input: ...

  9. HDU 3157 Crazy Circuits(有源汇上下界最小流)

    HDU 3157 Crazy Circuits 题目链接 题意:一个电路板,上面有N个接线柱(标号1~N),还有两个电源接线柱 + -.给出一些线路,每一个线路有一个下限值求一个能够让全部部件正常工作 ...

随机推荐

  1. Swing State: Consistent Updates for Stateful and Programmable Data Planes

    Swing State: Consistent Updates for Stateful and Programmable Data Planes 年份:2017 来源:ACM 本篇论文解决的问题 B ...

  2. C++对象模型 多重继承与虚函数表

    一 多重继承 1) 代码: Code#include <iostream>using namespace std; class B1{public:    int x;    virtua ...

  3. Spring+Netty4实现的简单通信框架

    参考:http://cpjsjxy.iteye.com/blog/1587601 Spring+Netty4实现的简单通信框架,支持Socket.HTTP.WebSocket_Text.WebSock ...

  4. 倒计时60s 代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 【第二周】【作业五】Scrum 每日站会

    1.首先来看一下什么是Scrum: Scrum是一种敏捷软件开发的方法学,用于迭代式增量软件开发过程.Scrum在英语是橄榄球运动中争球的意思. 虽然Scrum是为管理软件开发项目而开发的,它同样可以 ...

  6. IDEA配置Java Web项目

    IDEA部署maven tomcat的java web项目的关键配置:

  7. HDU4802_GPA

    水题. #include <iostream> #include <cstdio> #include <cstring> using namespace std; ...

  8. HDU4466_Triangle

    今天比赛做的一个题目,不过今天终于感受到了复旦题目有多坑了. 题目的意思是给你一段长为n个单位长度的直线,你可以选择任意连续单位长度的线段组成三角形,可以组成任意你可以组成任意多个三角形,且要求其中所 ...

  9. 【JavaScript&jQuery】单选框radio,复选框checkbox,下拉选择框select

    HTML: <!DOCTYPE html> <html> <head> <title></title> <meta charset=& ...

  10. C++解析(24):抽象类和接口、多重继承

    0.目录 1.抽象类和接口 1.1 抽象类 1.2 纯虚函数 1.3 接口 2.被遗弃的多重继承 2.1 C++中的多重继承 2.2 多重继承的问题一 2.3 多重继承的问题二 2.4 多重继承的问题 ...