zzuoj 10459: Tutti! 【最小费用最大流】
2016-04-10 11:33
375 查看
题目链接:zzuoj 10459: Tutti!
10459: Tutti!
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 12 Solved: 2
[Submit][Status][Web Board]
Description
因为Raywzy计划在清明节去爬泰山,所以他决定在去之前好好的锻炼一下身体,跑步是很好的办法!在zzu内,假设有N个房子,M条十字路口,保证寝室编号为1,实验室编号为N。Raywzy只能从一个十字路口跑向另一个十字路口,街道
之间只在十字路口处相交。
Raywzy的跑步计划是按周期进行的,而且他不喜欢走重复的路线,即每天选择一条不同的路线。除了1和N之外,每个点只能走一次。但是Raywzy十分的瘦弱,所以他想尽可能跑短的路线。现在Raywzy希望你可以为他定一个训练计划。
Raywzy每天的起点是1,目的地是实验室~~
内容与题目无关=w=
Input
数据保证单组
第一行2个数n,m。表示十字路口数和街道数。
接下来m行,每行3个数a,b,c,表示十字路口a和十字路口b之间有条长度为c的单向街道。
Output
2个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长度(即长度和)。
Sample Input
7 10
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
2 5 5
3 6 6
5 7 1
6 7 1
Sample Output
2 11
稍微思考就会发现这是最小费用最大流。。。
AC代码:
10459: Tutti!
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 12 Solved: 2
[Submit][Status][Web Board]
Description
因为Raywzy计划在清明节去爬泰山,所以他决定在去之前好好的锻炼一下身体,跑步是很好的办法!在zzu内,假设有N个房子,M条十字路口,保证寝室编号为1,实验室编号为N。Raywzy只能从一个十字路口跑向另一个十字路口,街道
之间只在十字路口处相交。
Raywzy的跑步计划是按周期进行的,而且他不喜欢走重复的路线,即每天选择一条不同的路线。除了1和N之外,每个点只能走一次。但是Raywzy十分的瘦弱,所以他想尽可能跑短的路线。现在Raywzy希望你可以为他定一个训练计划。
Raywzy每天的起点是1,目的地是实验室~~
内容与题目无关=w=
Input
数据保证单组
第一行2个数n,m。表示十字路口数和街道数。
接下来m行,每行3个数a,b,c,表示十字路口a和十字路口b之间有条长度为c的单向街道。
Output
2个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长度(即长度和)。
Sample Input
7 10
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
2 5 5
3 6 6
5 7 1
6 7 1
Sample Output
2 11
稍微思考就会发现这是最小费用最大流。。。
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> #include <cmath> #include <stack> #define fi first #define se second #define ll o<<1 #define rr o<<1|1 #define CLR(a, b) memset(a, (b), sizeof(a)) using namespace std; typedef long long LL; typedef pair<int, int> pii; const int MOD = 1e9 + 7; const int MAXN = 1e4 + 10; const int INF = 0x3f3f3f3f; void add(LL &x, LL y) { x += y; x %= MOD; } struct Edge { int from, to, cap, flow, cost, next; }; Edge edge[MAXN*50]; int head[MAXN], edgenum; void init() { CLR(head, -1); edgenum = 0; } void addEdge(int u, int v, int w, int c) { Edge E = {u, v, w, 0, c, head[u]}; edge[edgenum] = E; head[u] = edgenum++; Edge E1 = {v, u, 0, 0, -c, head[v]}; edge[edgenum] = E1; head[v] = edgenum++; } bool vis[MAXN]; int dist[MAXN], pre[MAXN]; bool SPFA(int s, int t) { queue<int> Q; CLR(dist, INF); CLR(vis, false); CLR(pre, -1); vis[s] = true; dist[s] = 0; Q.push(s); while(!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = false; for(int i = head[u]; i != -1; i = edge[i].next) { Edge E = edge[i]; if(dist[E.to] > dist[u] + E.cost && E.cap > E.flow) { dist[E.to] = dist[u] + E.cost; pre[E.to] = i; if(!vis[E.to]) { vis[E.to] = true; Q.push(E.to); } } } } return pre[t] != -1; } void MCMF(int s, int t, int &flow, int &cost) { flow = cost = 0; while(SPFA(s, t)) { int Min = INF; for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) { Edge E = edge[i]; Min = min(Min, E.cap - E.flow); } for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; cost += edge[i].cost * Min; } flow += Min; } } int main() { int n, m; while(scanf("%d%d", &n, &m) != EOF) { init(); for(int i = 2; i <= n-1; i++) { addEdge(i, i+n, 1, 0); } for(int i = 0; i < m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); if(u != 1 && u != n) u += n; addEdge(u, v, 1, w); } int flow, cost; MCMF(1, n, flow, cost); printf("%d %d\n", flow, cost); } return 0; }
相关文章推荐
- dual表
- LAMP服务的搭建
- 抽象类和接口
- 一道古老的分赃题之我见
- mapreduce(JAVA)实现(大数据)电话号码对应的流量排序(倒序)
- memcache在大型网站的应用策略
- POJ 3159 Candies(SPFA+栈)差分约束
- 复利计算-做汉堡,结对2.0
- 推荐《天才在左,疯子在右》
- Calling C and C++ from IDL (一)
- zzuoj 10456: 最长匹配子串 【思维】
- LeetCode *** 290. Word Pattern
- 《LeetBook》leetcode题解(8): String to Integer (atoi) [E]——正负号处理
- PHP_D4_“简易聊天室 ”的具体技术实现
- 随便取10 个数4
- Problem 1608 - Calculation 【状压dp】
- 目标特征检测之ORB
- hdu 5660 jrMz and angles【暴力枚举】【水题】
- 提取多层嵌套JSON类型数据
- Problem 1603 - Minimum Sum 【数学】