LA 2957 最大流,最短时间,输出路径
题意: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了。
#include <bits/stdc++.h> using namespace std; const int maxn = +;
const int INF = 0x3f3f3f3f; struct Edge{
int from,to,cap,flow;
}; bool operator < (const Edge& a,const Edge& b) {
return a.from < b.from||(a.from==b.from&&a.to<b.to);
} struct Dinic {
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn]; void init() {
edges.clear();
} void clearNodes(int a,int b) {
for(int i=a;i<=b;i++)
G[i].clear();
} void AddEdge(int from,int to,int cap) {
edges.push_back((Edge){from,to,cap,});
edges.push_back((Edge){to,from,,});
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS() {
memset(vis,,sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = ;
d[s] = ;
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i=;i<G[x].size();i++) {
Edge& e = edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow) {
vis[e.to] = ;
d[e.to] = d[x] + ;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a) {
if(x==t||a==) return a;
int flow = ,f;
for(int& i=cur[x];i<G[x].size();i++) {
Edge& e = edges[G[x][i]];
if(d[x]+==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>) {
e.flow +=f;
edges[G[x][i]^].flow-=f;
flow+=f;
a-=f;
if(a==) break;
}
}
return flow;
} int Maxflow(int s,int t,int limit) {
this->s = s;
this->t = t;
int flow = ;
while(BFS()) {
memset(cur,,sizeof(cur));
flow +=DFS(s,limit-flow);
if(flow==limit) break;
}
return flow;
}
}; Dinic g; int main()
{
int n,m,k,s,t;
int u[maxn],v[maxn]; while(~scanf("%d%d%d%d%d",&n,&m,&k,&s,&t)) {
for(int i=;i<m;i++) {
scanf("%d%d",&u[i],&v[i]);
}
g.init();
int day = ;
g.clearNodes(,n-);
int flow = ;
for(;;) {
g.clearNodes(day*n,day*n+n-);
for(int i=;i<n;i++)
g.AddEdge((day-)*n+i,day*n+i,INF);
for(int i=;i<m;i++) {
g.AddEdge((day-)*n+u[i]-,day*n+v[i]-,);
g.AddEdge((day-)*n+v[i]-,day*n+u[i]-,);
}
flow+=g.Maxflow(s-,day*n+t-,k-flow);
if(flow==k) break;
day++;
} printf("%d\n",day); int idx = ;
vector<int> location(k,s); for(int d=;d<=day;d++) {
idx +=n*;
vector<int> moved(k,);
vector<int> a,b; for(int i=;i<m;i++) {
int f1 = g.edges[idx].flow; idx+=;
int f2 = g.edges[idx].flow; idx+=;
if(f1==&&f2==) {
a.push_back(u[i]);
b.push_back(v[i]);
}
if(f1==&&f2==) {
a.push_back(v[i]);
b.push_back(u[i]);
}
} printf("%d",a.size());
for(int i=;i<a.size();i++) {
for(int j=;j<k;j++) { //找到具体是哪一个飞船
if(!moved[j]&&location[j]==a[i]) {
printf(" %d %d",j+,b[i]);
moved[j] = ;
location[j] = b[i];
break;
}
}
}
printf("\n"); } } return ;
}
LA 2957 最大流,最短时间,输出路径的更多相关文章
- PTA 紧急救援 /// dijkstra 最短路数 输出路径
题目大意: 给定 n m s t :表示n个点编号为0~n-1 m条边 起点s终点t 接下来一行给定n个数:表示第i个点的救援队数量 接下来m行给定u v w:表示点u到点v有一条长度为w的边 求从s ...
- POJ-3436(网络流+最大流+输出路径)
ACM Computer Factory POJ-3436 题目就是一个工厂n个加工机器,每个机器有一个效率w,q个材料入口,q个材料出口,每个口有三个数表示状态,1表示一定有入/出的材料,0表示没有 ...
- POJ 3684 Priest John's Busiest Day 2-SAT+输出路径
强连通算法推断是否满足2-sat,然后反向建图,拓扑排序+染色. 一种选择是从 起点開始,还有一种是终点-持续时间那个点 開始. 若2个婚礼的某2种时间线段相交,则有矛盾,建边. easy出错的地方就 ...
- UVA-624 CD---01背包+输出路径
题目链接: https://vjudge.net/problem/UVA-624 题目大意: 这道题给定一个时间上限,然后一个数字N,后面跟着N首歌的时间长度,要我们 求在规定时间w内每首歌都要完整的 ...
- Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
package org.xiu68.exp.exp10; import java.util.ArrayDeque; import java.util.ArrayList; import java.ut ...
- UVA 624 CD[【01背包】(输出路径)
<题目链接> 题目大意: 你要录制时间为N的带子,给你一张CD的不同时长的轨道,求总和不大于N的录制顺序 解题分析: 01背包问题,需要注意的是如何将路径输出. 由于dp时是会不断的将前面 ...
- hdu 1026(BFS+输出路径) 我要和怪兽决斗
http://acm.hdu.edu.cn/showproblem.php?pid=1026 模拟一个人走迷宫,起点在(0,0)位置,遇到怪兽要和他决斗,决斗时间为那个格子的数字,就是走一个格子花费时 ...
- 动态规划之DP中判断是否到达某一状态(最短时间是什么)?
codevs1684 垃圾陷阱 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 卡门——农夫约翰极其珍视的一条Holste ...
- IO流——递归(输出所有文件)
package pers.zbb.File; import java.io.File; public class FileDemo { public static void main(String[] ...
随机推荐
- Office 下载地址
Office Professional Plus 2013 64位简体中文版文件名: cn_office_professional_plus_2013_x64_dvd_1134006.iso语言: C ...
- Socket通信客户端和服务端代码
这两天研究了下Socket通信,简单实现的客户端和服务端代码 先上winfrom图片,客户端和服务端一样 服务端代码: using System; using System.Collections.G ...
- NMS_非极大值抑制(转)
NMS(non maximum suppression),中文名非极大值抑制,在很多计算机视觉任务中都有广泛应用,如:边缘检测.目标检测等. 这里主要以人脸检测中的应用为例,来说明NMS,并给出Mat ...
- 笔记_简明Python教程_Byte_of_Python
1. 局部变量.全局变量 局部变量: x = 50 def func(x): x = 2 print('Change local x to',x) func(x) print('x is still' ...
- js随机生成[n,m)的数字(不包括m)
Math.random();//随机生成0到1的数字 Math.floor();//取小整 Math.floor(Math.random()*(最大值 - 最小值) + 最小值) 生成2到8的数:Ma ...
- my.副本
梦幻西游手游 天蓬下凡 副本 第三关:天蓬终于决定要告白了,主怪大唐,护卫狮驼岭,帮凶是龙宫,打过这关也很简单. 第四关:康太尉找来了天兵,怪仍然是有法有攻,但是打起来也是不难. ZC: 姚太尉是物理 ...
- VMware Workstation 12.5.9 Pro虚拟机软件中文版
更新为 VMware Workstation 12.5.9 pro版.VMware虚拟机软件无疑是windows系统下最强大好用的虚拟机软件.最新的VMware Workstation 12 Pro ...
- c++中赋值运算符重载为什么要用引用做返回值?
class string{ public: string(const char *str=NULL); string(const string& str); //copy构造函数的参数 ...
- ubuntu15.04 xampp 安装memcache
要ThinkPHP3.2里由于要用到 memcache 缓存, 如果没有配置memcache,会报错,说系统支持 memcache. 所在配置的时候有点问题,现在解决了,现把它记录下来,以便以后查阅之 ...
- [HZOI 2015]复仇的序幕曲
[题目描述] 你还梦不梦痛不痛,回忆这么重你怎么背得动 ----序言 当年的战火硝烟已经渐渐远去,可仇恨却在阿凯蒂王子的心中越来越深 他的叔父三年前谋权篡位,逼宫杀死了他的父王,用铁血手腕平定了国内所 ...