LA 2957 最大流,最短时间,输出路径
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=159&page=show_problem&problem=958
题意:n个星球,用最短的时间把k个超级计算机从s运到t;
其中,每个隧道是双向的,一个隧道里面只能有一个飞船在使用,一个飞船上只有一台计算机。
分析:
一个隧道只能给一个飞船用,那么假设需要t天,那么可以这样建图:
u结点,拆成t+1个,分别是 u0,u1,u2,...,ut;
u0是u的初始状态,ui是u在第i天的状态,那么建图就是:
a结点到b结点,ai 到 bi+1 一条容量为1的边,bi 到 ai+1 的容量为1的一条边。
对于每个结点,都有ui到ui+1 的容量是无穷大,因为可以停留。
一天一天增加结点,终点也发生变化,流量直到为k,就结束了。
然后输出路径:
遍历原图的上的每一条边,注意edges是残余网络,idx+=2;这才加了一条边。
问题问的路径是(A,B)编号为A的飞机,到达行星 B,行星B就是有流量的那一条边都后面那个结点。那么,编号A怎么求呢?
可以遍历一下这k个飞机,如果 j 所在的位置location[j] = a[i] 的话,就ok了。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 5000+10; 6 const int INF = 0x3f3f3f3f; 7 8 struct Edge{ 9 int from,to,cap,flow; 10 }; 11 12 bool operator < (const Edge& a,const Edge& b) { 13 return a.from < b.from||(a.from==b.from&&a.to<b.to); 14 } 15 16 struct Dinic { 17 int n,m,s,t; 18 vector<Edge> edges; 19 vector<int> G[maxn]; 20 bool vis[maxn]; 21 int d[maxn]; 22 int cur[maxn]; 23 24 void init() { 25 edges.clear(); 26 } 27 28 void clearNodes(int a,int b) { 29 for(int i=a;i<=b;i++) 30 G[i].clear(); 31 } 32 33 void AddEdge(int from,int to,int cap) { 34 edges.push_back((Edge){from,to,cap,0}); 35 edges.push_back((Edge){to,from,0,0}); 36 m = edges.size(); 37 G[from].push_back(m-2); 38 G[to].push_back(m-1); 39 } 40 41 bool BFS() { 42 memset(vis,0,sizeof(vis)); 43 queue<int> Q; 44 Q.push(s); 45 vis[s] = 1; 46 d[s] = 0; 47 while(!Q.empty()) { 48 int x = Q.front(); Q.pop(); 49 for(int i=0;i<G[x].size();i++) { 50 Edge& e = edges[G[x][i]]; 51 if(!vis[e.to]&&e.cap>e.flow) { 52 vis[e.to] = 1; 53 d[e.to] = d[x] + 1; 54 Q.push(e.to); 55 } 56 } 57 } 58 return vis[t]; 59 } 60 61 int DFS(int x,int a) { 62 if(x==t||a==0) return a; 63 int flow = 0,f; 64 for(int& i=cur[x];i<G[x].size();i++) { 65 Edge& e = edges[G[x][i]]; 66 if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) { 67 e.flow +=f; 68 edges[G[x][i]^1].flow-=f; 69 flow+=f; 70 a-=f; 71 if(a==0) break; 72 } 73 } 74 return flow; 75 } 76 77 int Maxflow(int s,int t,int limit) { 78 this->s = s; 79 this->t = t; 80 int flow = 0; 81 while(BFS()) { 82 memset(cur,0,sizeof(cur)); 83 flow +=DFS(s,limit-flow); 84 if(flow==limit) break; 85 } 86 return flow; 87 } 88 }; 89 90 Dinic g; 91 92 int main() 93 { 94 int n,m,k,s,t; 95 int u[maxn],v[maxn]; 96 97 while(~scanf("%d%d%d%d%d",&n,&m,&k,&s,&t)) { 98 for(int i=0;i<m;i++) { 99 scanf("%d%d",&u[i],&v[i]); 100 } 101 g.init(); 102 int day = 1; 103 g.clearNodes(0,n-1); 104 int flow = 0; 105 for(;;) { 106 g.clearNodes(day*n,day*n+n-1); 107 for(int i=0;i<n;i++) 108 g.AddEdge((day-1)*n+i,day*n+i,INF); 109 for(int i=0;i<m;i++) { 110 g.AddEdge((day-1)*n+u[i]-1,day*n+v[i]-1,1); 111 g.AddEdge((day-1)*n+v[i]-1,day*n+u[i]-1,1); 112 } 113 flow+=g.Maxflow(s-1,day*n+t-1,k-flow); 114 if(flow==k) break; 115 day++; 116 } 117 118 printf("%d\n",day); 119 120 int idx = 0; 121 vector<int> location(k,s); 122 123 for(int d=1;d<=day;d++) { 124 idx +=n*2; 125 vector<int> moved(k,0); 126 vector<int> a,b; 127 128 for(int i=0;i<m;i++) { 129 int f1 = g.edges[idx].flow; idx+=2; 130 int f2 = g.edges[idx].flow; idx+=2; 131 if(f1==1&&f2==0) { 132 a.push_back(u[i]); 133 b.push_back(v[i]); 134 } 135 if(f1==0&&f2==1) { 136 a.push_back(v[i]); 137 b.push_back(u[i]); 138 } 139 } 140 141 printf("%d",a.size()); 142 for(int i=0;i<a.size();i++) { 143 for(int j=0;j<k;j++) { //找到具体是哪一个飞船 144 if(!moved[j]&&location[j]==a[i]) { 145 printf(" %d %d",j+1,b[i]); 146 moved[j] = 1; 147 location[j] = b[i]; 148 break; 149 } 150 } 151 } 152 printf("\n"); 153 154 } 155 156 } 157 158 return 0; 159 }
转载于:https://www.cnblogs.com/TreeDream/p/6539460.html
LA 2957 最大流,最短时间,输出路径相关推荐
- POJ3426 ACM Computer Factory——最大流(EK+输出路径)
点这里 题意: 题目大意就是问把000加工到111(多少个零视输入的P而定)的最大零件个数,并且输出路径. 但是具体的加工规则真的是把我看晕了 然后我们来说说具体的加工规则:N台机器,每台机器能同 ...
- 【算法设计与分析】分支限界法解决单源最短路径问题:输入带权图G=(V,E)以及出发顶点s,然后用分支限界法解决问题,要求输出路径和长度以及计算时间;
目的: 1.掌握分支限界法的基本思想: 2.掌握解决单源最短路径问题的分支限界法实现方法: 3.学会分析算法的时间复杂度: 4.学会用分支限界法解决实际问题. 要求: 1.输入带权图G=(V,E)以及 ...
- java输入和输出路径_Java输入输出
Java输入输出学习 File类 File类是java.io包下代表与平台无关的文件和目录,也就是说,如果希望在程序中操作文件和目录,都可以通过File类来完成.值得指出的是,不管是文件还是目录都是使 ...
- 最短路径 输出路径 Dijkstra算法
这个问题难受了半天终于搞懂了,来给分享一下 先弄个例子看看: B.wzy的大冒险--出发咯QAQ wzy踏上了冒险的旅程. 现在他从地精手里买了一份地图,地图上有n个城镇. 他从第一个城镇出发,走向( ...
- 迪杰斯特拉--- 模板(求最短路径/输出路径/所有路径都可以走的做法)
迪杰斯特拉--- 模板(求最短路径/输出路径/所有路径都可以走的做法) 1.0版 #include <iostream> using namespace std;const int max ...
- js \n直接显示字符串_显示N个字符的最短时间
js \n直接显示字符串 Problem statement: 问题陈述: You need to display N similar characters on a screen. You are ...
- Flink FileSink 自定义输出路径——BucketingSink
今天看到有小伙伴在问,就想着自己实现一下. 问题: Flink FileSink根据输入数据指定输出位置,比如讲对应日期的数据输出到对应目录 输入数据: 20190716 输出到路径 20190716 ...
- 【LeetCode每日一题】1723. 完成所有工作的最短时间
[LeetCode每日一题]1723. 完成所有工作的最短时间 [1] 1723. 完成所有工作的最短时间 [2] 473. 火柴拼正方形 [1] 1723. 完成所有工作的最短时间 题目: 给你一个 ...
- [leetcode每日一题2021/5/8]1723. 完成所有工作的最短时间
1723. 完成所有工作的最短时间 题目 思路 动态规划 状态转移方程 优化 求和打表 快速枚举每种选取情况jjj的子集ppp 代码 算法复杂度 题目来源于leetcode,解法和思路仅代表个人观点. ...
最新文章
- 外网主机访问虚拟机下的Web服务器_服务器应用_Linux公社-Linux系统门户网站
- 管理员修改文件的权限
- html得到画布的颜色的值,从画布上获取像素颜色
- python编程基础语法-Python编程基础语法快速入门
- 如何编写php解析器_用于PHP的HL7解析器/编写器
- spring boot源码分析之SpringApplication
- C#比较数组内元素相等-冒泡
- Linux系统 proc self,Linux内核源代码情形分析-特殊文件系统/proc-对/proc/self/cwd的访问...
- AttributeError: module 'pymongo' has no attribute 'Connection'
- 带有骆驼,ActiveMQ,Elasticsearch的HL7关键用例
- iphone型号表_机器人造iPhone,苹果奋斗八年,还是败给了富士康工人
- secp256r1 c语言程序,rust代码阅读 之 libsecp256k1 (1)
- 计算机网络体系结构物流层,计算机网络体系结构58029.ppt
- AIX 6.1环境 yum的安装方法
- XE Styles不见了
- Java中用split函数进行分割字符串。
- Java实现爬取哔哩哔哩视频信息程序
- 《增强现实:融合现实与虚拟世界》
- tomcat启动错误Error deploying web application directory
- 【新书】崛起的超级智能:互联网大脑如何影响科技未来
热门文章
- 小米手机连接不上网络 或者 暂时关闭状况不佳的连接
- 请问:如何在C#简单分布式程序的数据层中为其它层留出很好的接口?????...
- u-boot源码配置原理分析
- atoi 原来将字符串02002xzm100转换为int以后是2002
- AndroidStudio安卓原生开发_UI高级_StateListDrawable状态选择器_按钮按下和抬起显示不同颜色---Android原生开发工作笔记124
- 微服务升级_SpringCloud Alibaba工作笔记0025---Nacos持久化切换配置
- springcloud工作笔记098---springcloud多项目包扫描问题
- 2015年3月29号日报
- GetTickCount() 函数的作用和用法(转)
- 杭电1874畅通工程续