2324: [ZJOI2011]营救皮卡丘

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1777  Solved: 712
[Submit][Status][Discuss]

Description

皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路。

火箭队一共有N个据点,据点之间存在M条双向道路。据点分别从1到N标号。小智一行K人从真新镇出发,营救被困在N号据点的皮卡丘。为了方便起见,我们将真新镇视为0号据点,一开始K个人都在0号点。

由于火箭队的重重布防,要想摧毁K号据点,必须按照顺序先摧毁1到K-1号据点,并且,如果K-1号据点没有被摧毁,由于防御的连锁性,小智一行任何一个人进入据点K,都会被发现,并产生严重后果。因此,在K-1号据点被摧毁之前,任何人是不能够经过K号据点的。

为了简化问题,我们忽略战斗环节,小智一行任何一个人经过K号据点即认为K号据点被摧毁。被摧毁的据点依然是可以被经过的。

K个人是可以分头行动的,只要有任何一个人在K-1号据点被摧毁之后,经过K号据点,K号据点就被摧毁了。显然的,只要N号据点被摧毁,皮卡丘就得救了。

野外的道路是不安全的,因此小智一行希望在摧毁N号据点救出皮卡丘的同时,使得K个人所经过的道路的长度总和最少。

请你帮助小智设计一个最佳的营救方案吧!

Input

第一行包含三个正整数N,M,K。表示一共有N+1个据点,分别从0到N编号,以及M条无向边。一开始小智一行共K个人均位于0号点。

接下来M行,每行三个非负整数,第i行的整数为Ai,Bi,Li。表示存在一条从Ai号据点到Bi号据点的长度为Li的道路。

Output

仅包含一个整数S,为营救皮卡丘所需要经过的最小的道路总和。

Sample Input

3 4 2
0 1 1
1 2 1
2 3 100
0 3 1

Sample Output

3
【样例说明】
小智和小霞一起前去营救皮卡丘。在最优方案中,小智先从真新镇前往1号点,接着前往2号据点。当小智成功摧毁2号据点之后,小霞从真新镇出发直接前往3号据点,救出皮卡丘。

HINT

对于100%的数据满足N ≤ 150, M ≤ 20 000, 1 ≤ K ≤ 10, Li ≤ 10 000, 保证小智一行一定能够救出皮卡丘。至于为什么K ≤ 10,你可以认为最终在小智的号召下,小智,小霞,小刚,小建,小遥,小胜,小光,艾莉丝,天桐,还有去日本旅游的黑猫警长,一同前去大战火箭队。

Source

【思路】

Floyd+费用流。

题目条件:1 每个点都必须经过 , 2 经过j时必须已经经过了0..j-1

利用floyd求出对点之间的最短距,转化为DAG即保证条件2。求DAG上至多不超过k条的覆盖路。

构图:每个点建立XY结点,连边(S,0,K,0)(S,Xi,1,0)(Yi,T,1,0),如果DAG上i,j之间有边,则连边(Xi,Yj,1,d[i][j])。

【代码】

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<vector>
  5. #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
  6. using namespace std;
  7.  
  8. typedef long long LL ;
  9. const int maxn = +;
  10. const int INF = 1e9;
  11.  
  12. struct Edge{ int u,v,cap,flow,cost;
  13. };
  14. struct zkw {
  15. int n,m,s,t;
  16. int vis[maxn],d[maxn];
  17. vector<int> G[maxn];
  18. vector<Edge> es;
  19.  
  20. void init(int n) {
  21. this->n=n;
  22. es.clear();
  23. for(int i=;i<n;i++) G[i].clear();
  24. }
  25. void AddEdge(int u,int v,int cap,int cost) {
  26. es.push_back((Edge){u,v,cap,,cost});
  27. es.push_back((Edge){v,u,,,-cost});
  28. m=es.size();
  29. G[u].push_back(m-);
  30. G[v].push_back(m-);
  31. }
  32. bool spfa() {
  33. memset(vis,,sizeof(vis));
  34. for(int i=;i<n;i++) d[i]=INF;
  35. queue<int> q;
  36. d[t]= , vis[t]= , q.push(t);
  37. while(!q.empty()) {
  38. int u=q.front(); q.pop() , vis[u]=;
  39. for(int i=;i<G[u].size();i++) {
  40. Edge& e=es[G[u][i]];
  41. int v=e.v;
  42. if(es[G[u][i]^].cap && d[v]>d[u]-e.cost) {
  43. d[v]=d[u]-e.cost;
  44. if(!vis[v]) {
  45. vis[v]=;
  46. q.push(v);
  47. }
  48. }
  49. }
  50. }
  51. return d[s]!=INF;
  52. }
  53. int dfs(int u,int a,LL& cost) {
  54. vis[u]=; if(u==t) return a;
  55. int used=,w;
  56. for(int i=;i<G[u].size();i++) {
  57. Edge& e=es[G[u][i]];
  58. int v=e.v;
  59. if(d[u]-e.cost==d[v] && !vis[v] && e.cap) {
  60. w=dfs(v,min(a-used,e.cap),cost);
  61. cost+=w*e.cost;
  62. e.cap-=w , es[G[u][i]^].cap+=w;
  63. used+=w; if(used==a) return a;
  64. }
  65. }
  66. return used;
  67. }
  68. int Mincost(int s,int t,LL& cost) {
  69. this->s=s , this->t=t;
  70. int flow=; cost=;
  71. while(spfa()) {
  72. vis[t]=;
  73. while(vis[t]) {
  74. memset(vis,,sizeof(vis));
  75. flow+=dfs(s,INF,cost);
  76. }
  77. }
  78. return flow;
  79. }
  80. } mc;
  81.  
  82. int n,m,K;
  83. int d[maxn][maxn];
  84.  
  85. int main() {
  86. scanf("%d%d%d",&n,&m,&K);
  87. mc.init(n+n+);
  88. int s=n+n+,t=s+;
  89. int u,v,w;
  90. FOR(i,,n) FOR(j,,n) d[i][j]=INF;
  91. FOR(i,,m) {
  92. scanf("%d%d%d",&u,&v,&w);
  93. d[u][v]=d[v][u]=min(d[u][v],w); //重边
  94. }
  95. FOR(k,,n) FOR(i,,n) FOR(j,,n)
  96. if(k<=j || k<=i) d[i][j]=min(d[i][k]+d[k][j],d[i][j]);
  97. mc.AddEdge(s,n+,K,);
  98. FOR(i,,n) {
  99. mc.AddEdge(s,i+n+,,);
  100. mc.AddEdge(i,t,,);
  101. }
  102. FOR(i,,n) FOR(j,i+,n)
  103. if(d[i][j]!=INF) mc.AddEdge(i+n+,j,,d[i][j]);
  104. LL cost;
  105. mc.Mincost(s,t,cost);
  106. printf("%lld",cost);
  107. return ;
  108. }

bzoj 2324 [ZJOI2011]营救皮卡丘(floyd,费用流)的更多相关文章

  1. BZOJ 2324: [ZJOI2011]营救皮卡丘( floyd + 费用流 )

    昨晚写的题...补发一下题解... 把1~N每个点拆成xi, yi 2个. 预处理i->j经过编号不超过max(i,j)的最短路(floyd) S->0(K, 0), S->xi(1 ...

  2. BZOJ2324 [ZJOI2011]营救皮卡丘 【费用流】

    题目 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双向道 ...

  3. BZOJ 2324: [ZJOI2011]营救皮卡丘(带上下限的最小费用最大流)

    这道题么= =还是有些恶心的,第一次写带上下界的网络流,整个人都萌萌哒~~~ 首先先预处理得最短路后 直接用费用流做就行了。 第一次写,还是挺好写的= = CODE: #include<cstd ...

  4. bzoj 2324: [ZJOI2011]营救皮卡丘

    #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #inclu ...

  5. 【洛谷P4542】 [ZJOI2011]营救皮卡丘(费用流)

    洛谷 题意: 给出\(n\)个点,\(m\)条边,现在有\(k,k\leq 10\)个人从\(0\)号点出发前往\(n\)点. 规定若某个人想要到达\(x\)点,则\(1\)~\(x-1\)号点都有人 ...

  6. BZOJ.2324.[ZJOI2011]营救皮卡丘(费用流 Floyd)

    BZOJ 洛谷 首先预处理出\(dis[i][j]\),表示从\(i\)到\(j\)的最短路.可以用\(Floyd\)处理. 注意\(i,j\)是没有大小关系限制的(\(i>j\)的\(dis[ ...

  7. 【洛谷 P4542】 [ZJOI2011]营救皮卡丘(费用流)

    题目链接 用最多经过\(k\)条经过\(0\)的路径覆盖所有点. 定义\(ds[i][j]\)表示从\(i\)到\(j\)不经过大于\(max(i,j)\)的点的最短路,显然可以用弗洛伊德求. 然后每 ...

  8. bzoj 2324 ZJOI 营救皮卡丘 费用流

    题的大概意思就是给定一个无向图,边有权值,现在你有k个人在0点,要求走到n点,且满足 1:人们可以分头行动,可以停在某一点不走了 2:当你走到x时,前x-1个点必须全部走过(不同的人走过也行,即分两路 ...

  9. P4542-[ZJOI2011]营救皮卡丘【费用流,Floyd】

    正题 题目链接:https://www.luogu.com.cn/problem/P4542 题目大意 给出\(n+1\)个点\(m\)条边的无向图,\(k\)个人开始在\(0\)号点,一个人进入\( ...

随机推荐

  1. "库未注册"(Library not registered)异常.

    启发链接:http://social.msdn.microsoft.com/Forums/vstudio/en-US/f25b80bc-ecd4-4c37-8be3-9106a765b072/libr ...

  2. SQL SERVER 存储过程基础

    一.注释 -- 单行注释,从这到本行结束为注释,类似C++,c#中// /* … */ 多行注释,类似C++,C#中/* … */ 二.变量 (int, smallint, tinyint, deci ...

  3. iOS 里面如何使用第三方应用程序打开自己的文件,调用wps其他应用打开当前应用里面的的ppt doc xls

    我们的自己的应用里面经常涉及的要打开ppt doc,这样的功能,以前总以为iOS沙盒封闭化,不可能实现,后来终于解决了 使用 UIDocumentInteractionController 来解决这一 ...

  4. ios里面如何压缩图片

    在iOS里面,压缩图片跟在其他环境里面差不多,都和累死, 就是对当前图片从新画图,制定一个尺寸的问题 UIImage* image = [UIImage imageNamed:@"cat.j ...

  5. WampServer修改端口及菜单Localhost

    一.修改Apache端口 1.在界面中选Apache,弹出隐藏菜单选项,打开配置文件httpd.conf: 2.找到 Listen 80: 3.将 80 改成 8080(当然自己也可以设定别的不使用的 ...

  6. I/O多路转接之select

    系统提供select函数来实现多路复⽤用输入/输出模型.select系统调用是用来让我们的程序监视 多个文件句柄的状态变化的.程序会停在select这里等待,直到被监视的文件句柄有一个或 多个发生了状 ...

  7. Windows程序设计 贪吃蛇c

    看Windows程序有段时间了,终于动手写东西.贪吃蛇算是一个开始吧,下面的贪吃蛇很简单,也有很多地方需要修改,还有情况没有考虑QAQ 但这不是我的目的了... 思路很简单:建个链表储存蛇身节点即可. ...

  8. .getBoundingClientRect()

    .getBoundingClientRect() 该方法获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置,他返回的是一个对象,即Object,该对象有4个属性:top,left,right, ...

  9. PHP常用代码段:

    1.PHP加密解密   function encryptDecrypt($key, $string, $decrypt){      if($decrypt){          $decrypted ...

  10. php基于数组的分页实现

    关于数组的分页函数,用数组进行分页的好处是可以方便的进行联合多表查询,只需要将查询的结果放在数组中就可以了以下是数组分页的函数,函数page_array用于数组的分页,函数show_array用于分页 ...