您的位置:首页 > 其它

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代码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: