【BZOJ 1877】【SDOI 2009】晨跑

拆点跑$MCMF最小费用最大流$

复习一下$MCMF$模板啦啦啦~~~

一些坑:更新$dist$后要接着更新$pre$,不要判断是否在队列中再更新,,,听不懂吧,听不懂就对了,因为只有我才会在这种错误上犯逗$TwT$

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 205
#define M 20005
#define mo 410
#define read(x) x=getint()
using namespace std;
inline int getint() {int k = 0, fh = 1; char c = getchar();	for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = k * 10 + c - '0'; return k * fh;}
struct node {
	int nxt, to, c, cost;
} E[(N << 1) + (M << 1)];
bool vis[mo];
int point[mo], pre[mo], n, m, cnt = 1, q[mo], dist[mo];
inline void ins(int x, int y, int z, int c) {
	E[++cnt].nxt = point[x]; E[cnt].to = y; E[cnt].c = z; E[cnt].cost = c; point[x] = cnt;
	E[++cnt].nxt = point[y]; E[cnt].to = x; E[cnt].c = 0; E[cnt].cost = -c; point[y] = cnt;
}
inline bool spfa(int s, int t) {
	for(int i = 1; i <= ((n - 1) << 1); ++i)
		dist[i] = 0x7fffffff;
	int head = 0, tail = 1;
	q[1] = s; vis[s] = 1; dist[s] = 0;
	while (head != tail) {
		++head; if (head == mo) head = 0;
		int u = q[head];
		vis[u] = 0;
		for(int tmp = point[u]; tmp; tmp = E[tmp].nxt) 
			if (E[tmp].c > 0) {
				int v = E[tmp].to;
				if (dist[u] + E[tmp].cost < dist[v]) {
					dist[v] = dist[u] + E[tmp].cost;
					pre[v] = tmp;
					if (!vis[v]) {
						++tail; if (tail == mo) tail = 0;
						q[tail] = v;
						vis[v] = 1;
					}
				}
			}
	}
	return dist[t] != 0x7fffffff;
}
inline void MCMF(int s, int t) {
	int a1 = 0, a2 = 0, flow, now;
	while (spfa(s, t)) {
		++a1;
		flow = 0x7fffffff;
		for(now = pre[t]; now; now = pre[E[now ^ 1].to])
			flow = min(flow, E[now].c);
		for(now = pre[t]; now; now = pre[E[now ^ 1].to])
			a2 += E[now].cost * flow, E[now].c -= flow, E[now ^ 1].c += flow;
	}
	printf("%d %d\n", a1, a2);
}
int main() {
	read(n); read(m);
	for(int i = 2; i < n; ++i)
		ins((i << 1) - 1, i << 1, 1, 0);
	int u, v, e;
	for(int i = 1; i <= m; ++i) {
		read(u); read(v); read(e);
		if (u == 1)
			if (v == n) ins(1, 2, 1, e);
			else ins(1, (v << 1) - 1, 1, e);
		else if (v == n)
			ins(u << 1, 2, 1, e);
		else
			ins(u << 1, (v << 1) - 1, 1, e);
	}
	MCMF(1, 2);
	return 0;
}

hhh

posted @ 2016-04-04 11:26  abclzr  阅读(185)  评论(0编辑  收藏  举报