题目链接: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了。

 #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 最大流,最短时间,输出路径的更多相关文章

  1. PTA 紧急救援 /// dijkstra 最短路数 输出路径

    题目大意: 给定 n m s t :表示n个点编号为0~n-1 m条边 起点s终点t 接下来一行给定n个数:表示第i个点的救援队数量 接下来m行给定u v w:表示点u到点v有一条长度为w的边 求从s ...

  2. POJ-3436(网络流+最大流+输出路径)

    ACM Computer Factory POJ-3436 题目就是一个工厂n个加工机器,每个机器有一个效率w,q个材料入口,q个材料出口,每个口有三个数表示状态,1表示一定有入/出的材料,0表示没有 ...

  3. POJ 3684 Priest John&#39;s Busiest Day 2-SAT+输出路径

    强连通算法推断是否满足2-sat,然后反向建图,拓扑排序+染色. 一种选择是从 起点開始,还有一种是终点-持续时间那个点 開始. 若2个婚礼的某2种时间线段相交,则有矛盾,建边. easy出错的地方就 ...

  4. UVA-624 CD---01背包+输出路径

    题目链接: https://vjudge.net/problem/UVA-624 题目大意: 这道题给定一个时间上限,然后一个数字N,后面跟着N首歌的时间长度,要我们 求在规定时间w内每首歌都要完整的 ...

  5. Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。

    package org.xiu68.exp.exp10; import java.util.ArrayDeque; import java.util.ArrayList; import java.ut ...

  6. UVA 624 CD[【01背包】(输出路径)

    <题目链接> 题目大意: 你要录制时间为N的带子,给你一张CD的不同时长的轨道,求总和不大于N的录制顺序 解题分析: 01背包问题,需要注意的是如何将路径输出. 由于dp时是会不断的将前面 ...

  7. hdu 1026(BFS+输出路径) 我要和怪兽决斗

    http://acm.hdu.edu.cn/showproblem.php?pid=1026 模拟一个人走迷宫,起点在(0,0)位置,遇到怪兽要和他决斗,决斗时间为那个格子的数字,就是走一个格子花费时 ...

  8. 动态规划之DP中判断是否到达某一状态(最短时间是什么)?

    codevs1684 垃圾陷阱  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold   题目描述 Description 卡门——农夫约翰极其珍视的一条Holste ...

  9. IO流——递归(输出所有文件)

    package pers.zbb.File; import java.io.File; public class FileDemo { public static void main(String[] ...

随机推荐

  1. python3 continue和break 区别

    for i in range(10): if i==5: continue #跳出当次循环 if i==8: break #跳出整个for循环 print(i)

  2. 在MD中使用Emoji

    mark语法中支持emoji表情 具体语法是:emoji: 比如我输入 :smile: 就会出现微笑

  3. ssh两台主机建立信任关系

    A主机(10.104.11.107)   B主机(10.104.11.128) A: ssh-keygen -t rsa [root@H0f .ssh]# ssh-keygen -t rsa Gene ...

  4. Sublime text中文乱码解决办法

    ConvertToUTF8 安装这个插件可以解决编码混乱问题 首先必须先配一下Sublime text ,安装 Package Control 1.  用Sublimt text 打开任意一个文件,C ...

  5. Sequelize Docs 中文文档 v4

    Sequelize Docs 中文文档 v4 写在前面 Sequelize 是一个基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, SQLite 和 Mi ...

  6. ArrayList代码分析

    集合算是java中最常用的部分了,阅读该部分jdk代码可以让我们更加清楚的了解其实现原理,在使用时也能心中有数,有利于写出高质量的代码. ArrayList 底层数组实现,初始长度10,超过长度后的自 ...

  7. The function getUserId must be used with a prefix when a default namespace is not specified 解决办法

    The function getUserId must be used with a prefix when a default namespace is not specified 解决方法: 1. ...

  8. POJ 1182——食物链——————【种类并查集】

    食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status P ...

  9. OAuth2.0和企业内部统一登录,token验证方式,OAuth2.0的 Authorization code grant 和 Implicit grant区别

    统一登录是个很多应用系统都要考虑的问题,多个项目的话最好前期进行统一设计,否则后面改造兼容很麻烦: cas认证的方式:新公司都是老项目,用的是cas认证的方式,比较重而且依赖较多,winform的项目 ...

  10. Spring-cloud微服务 Eureka学习教程-分布式搭建EurekaServer、EurekaClient+Ribbon(中级)

    我们这里只有一台服务器,所以我们先仿集群搭建. 完整demo项目代码:https://github.com/wades2/EurekaDemo2 在这之前我们先分析分析Eureka相比其他注册中心的好 ...