网络流:宇宙旅行
来源:互联网 发布:云南农业大学网络考试 编辑:程序博客网 时间:2024/05/11 06:03
1. 题目要求
在走遍了地球上的所有景点以后,旅游狂人开始计划他的宇宙旅行项目。经过谨慎调查,他目前掌握了一张各卫星空间站可以临时容纳的旅客人数的列表。当旅客从一个星球飞往另一个星球时,需要在若干卫星空间站临时停靠中转,而这些空间站不能接待任何旅客驻留,旅客必须立刻转乘另一艘飞船离开,所以空间站不能接待超过自己最大容量的旅客流。为了估计预算,现在旅游狂人需要知道终点星球的接待站应该设计多大容量,才能使得每艘飞船在到达时都可以保证让全部旅客下船。2. 输入要求
输入由若干组测试数据组成。每组测试数据的第一行包含旅行的起点星球和终点星球的名称和一个不超过500的正整数N(N为0标志全部测试结束,不要对该数据做任何处理)。
接下来的N行里,数据格式为:(以下的i为下标)sourcei
测试数据中不包含任何到达起点星球的信息以及任何从终点星球出发的信息。
3. 输出要求:
对每一组测试,在一行里输出终点星球接待站应具有的最小容量,使得每艘飞船在到达时都可以保证让全部旅客下船。4. 输入例子
EAREAR
EAR
AAA
AAA
BBB
AAA
CCC
DDD
EAR
EAR
AAA
EAR
AAA
AAA
DDD
CCC
BBB
ABC
5. 输出例子
500500
6. 简要提示
该题目中给定了起点和终点(星球),其他结点(空间站)的流入量必须等于流出量,建议用网络流(Network实现时注意,程序应能在2秒内处理10组最大规模(N=500)的测试用例。为提高程序效率,需要为节点名建立散列表,避免在查找节点名上浪费时间。
所以这个题目的实现涉及3种算法:最短路径、散列映射、网络流。
测试时应注意边界测试,需要写个程序生成N为500的输入。
7.代码
#include <stdio.h>#include <string.h>#include <vector>#include<iostream>using namespace std;#define MAX_N 1001#define INF 0xffffff#define min(a, b) (a < b ? a : b)struct edge{ int to, cap; int rev; edge(int t, int c, int r) { to = t; cap = c; rev = r; }};vector<edge> G[MAX_N];bool visited[MAX_N];int n, m;// 每对顶点添加正反边void addEdge(int from, int to, int cap){ G[from].push_back(edge(to, cap, G[to].size())); G[to].push_back(edge(from, 0, G[from].size() - 1));}int dfs(int v, int t, int f){ int i; if (v == t) { return f; } visited[v] = true; for (i = 0; i < G[v].size(); i++) { edge &e = G[v][i]; if (!visited[e.to] && e.cap > 0) { int d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0;}int maxFlow(int s, int t){ int flow = 0; while (true) { memset(visited, 0, sizeof(visited)); int f = dfs(s, t, INF); if (f == 0) { return flow; } flow += f; }}char points[MAX_N][4];int getIndex(char s[]){ int i; for(i=0; i<MAX_N; i++) { if(strlen(points[i])==0) { strcpy(points[i],points[i-1]); strcpy(points[i-1],s); return i-1; } else if(strcmp(points[i],s)==0) { return i; } } return 0;}void ini(){ int i; for(i=0; i<MAX_N; i++) { G[i].clear(); points[i][0]='\0'; }}int getCount(){ int i; for(i=0; i<MAX_N; i++) { if(strlen(points[i])==0) return i; }}int main(){ int i, j ,n; int from, to, cap; char src[4],des[4]; char f[4],t[4]; ini(); while(1) { scanf("%s%s%d",f,t,&n); if(n==0) break; ini(); strcpy(points[0],f); strcpy(points[1],t); for(i=0; i<n; i++) { scanf("%s%s%d",src,des,&cap); addEdge(getIndex(src), getIndex(des), cap); } printf("%d\n", maxFlow(0, getCount() - 1)); } return 0;}
java
import java.util.*;public class Test1 {final static int max = 1001;final static int inf = 0xffffff;private static String points[] = new String[max];private static Vector<Edge> g[] = new Vector[max];private static boolean visited[] = new boolean[max];static class Edge {int to, cap, rev;Edge(int to, int cap, int rev) {this.to = to;this.cap = cap;this.rev = rev;}}public static void main(String[] args) {for (int i = 0; i < max; i++)g[i] = new Vector<Edge>();int n;int cap;String f, t;String src, des;ini();Scanner cin = new Scanner(System.in);while (true) {f = cin.next();t = cin.next();n = cin.nextInt();if (n == 0)break;ini();points[0] = f;points[1] = t;for (int i = 0; i < n; i++) {src = cin.next();des = cin.next();cap = cin.nextInt();addEdge(getIndex(src), getIndex(des), cap);}/*for (int i = 0; i < max; i++) {if (points[i] != null)System.out.println(points[i]);}*/System.out.println(maxFlow(0, getCount() - 1));}}private static void addEdge(int from, int to, int cap) {g[from].add(new Edge(to, cap, g[to].size())); //System.out.println(to+" "+cap+" "+g[to].size());g[to].add(new Edge(from, 0, g[from].size() - 1));}private static int getIndex(String s) {for (int i = 0; i < max; i++) {// if (points[i] != null)// System.out.println(points[i] + s);if (points[i] == null) {points[i] = points[i - 1];points[i - 1] = s;return i - 1;} else if (points[i].equals(s))return i;}return 0;}private static void ini() {for (int i = 0; i < max; i++) {g[i].clear();points[i] = null;}}private static int getCount() {for (int i = 0; i < max; i++) {if (points[i] == null)return i;}return 0;}private static int maxFlow(int s, int t) {int flow = 0; //System.out.println(s+" "+t+" ");while (true) {for (int i = 0; i < max; i++) {visited[i] = false;}int f = dfs(s, t, inf);if (f == 0)return flow;// System.out.println(flow);flow += f;}}private static int dfs(int v, int t, int f) {if (v == t) {return f;}visited[v] = true;for (int i = 0; i < g[v].size(); i++) {Edge e = g[v].get(i);if (!visited[e.to] && e.cap > 0) {int d = dfs(e.to, t, min(f, e.cap));// System.out.println(d);if (d > 0) {e.cap -= d;g[e.to].get(e.rev).cap += d;return d;}}}return 0;}private static int min(int a, int b) {return a > b ? b : a;}}
1 0
- 网络流:宇宙旅行
- 【jzoj4832】【高维宇宙】【网络流】【二分图匹配】
- 宇宙
- 宇宙
- BZOJ 1570 JSOI2008 Blue Mary的旅行 网络流
- BZOJ 1570 JSOI 2008 Blue Mary的旅行 网络流
- Codeforces 546E:士兵的旅行 最大网络流
- 1570: [JSOI2008]Blue Mary的旅行|网络流
- jzoj 4832. 【NOIP2016提高A组集训第3场10.31】高维宇宙 网络流或状压dp
- bzoj 1917: [Ctsc2010]星际旅行 树形dp解决树上网络流
- 51nod 1442 士兵的旅行 【 网络费用流 (还存在bug) 】
- bzoj 1570: [JSOI2008]Blue Mary的旅行 分层图网络流
- 旅行
- 旅行
- 旅行...
- 旅行
- 旅行
- 旅行
- 动态链接库
- samba 配置
- 语音识别
- Eclipse使用技巧
- 团队带领问题
- 网络流:宇宙旅行
- Spring的配置文件
- 软件项目的过程评审
- ExtJs4学习(十三)如何给文件上传按钮加背景图片
- Android Scroller类的详细分析
- 进程控制理论知识
- Makefile, Kconfig和.config关联关系
- 如何做好项目需求获取与分析
- 文件绝对路径和相对路径