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[] ...
随机推荐
- 在Pycharm上编写WordCount程序
本篇博客将给大家介绍怎么在PyCharm上编写运行WordCount程序. 第一步 下载安装PyCharm 下载Pycharm PyCharm的下载地址(Linux版本).下载完成后你将得到一个名叫: ...
- WireShark抓包分析(二)
简述:本文介绍了抓包数据含义,有TCP报文.Http报文.DNS报文.如有错误,欢迎指正. 1.TCP报文 TCP:(TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP ...
- Doxygen生成美丽注释文档(1):初体验
Chapter 1 - 准备工作 (Windows环境) 1.1 程序包下载 1. Doxygen * 源码: git clone https://github.com/doxygen/doxygen ...
- NET Core 不错教程***************
Twinhead 当前标签: .Net Core RabbitMQ教程 Twinhead 2019-01-26 20:02 阅读:5 评论:0 缓存击穿.缓存穿透和缓存雪崩 Twinhea ...
- vue中this.$router.push() 传参
1 params 传参 注意⚠️:patams传参 ,路径不能使用path 只能使用name,不然获取不到传的数据 this.$router.push({name: 'dispatch', para ...
- 安装tomcat时遇到的问题
1.刚开始在eclipse配置的tomcat是免安装的,后来提示 所以后来配置了一个安装版的. 2.后来运行server发现报错:8080,8005,端口被占用,然后关闭xammp上的server,然 ...
- 爬虫(GET)——爬取多页的html
工具:python3 目标:将编写的代码封装,不同函数完成不同功能,爬取任意页数的html 新学语法:with open as 除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常. # ...
- sqlt 之 分析 DB upgrade 导致SQL 性能下降 的方法 xplore
https://blog.csdn.net/lukeUnique/article/details/79331779 https://mauro-pagano.com/2014/10/27/when-t ...
- Python APIs
NDArray API Python API速查
- C# 判断字符串为空(长度为0),或者是null(没有new)
string str = null; if (string.IsNullOrWhiteSpace(str)) { MessageBox.Show("字符串为null"); } ) ...