POJ1149 PIGS

想了好久啊。。。(#-.-)

开始想到m*n个点的构图,明显超时,于是考虑压缩节点个数

我们发现每个猪圈最后被有且只有一个人调整,于是想到对于一个人,连接他能调整的每个猪圈的上一个控制人。(不懂可以开代码  (・(ェ)・)   )

/**

 * Problem:POJ1149

 * Author:Shun Yao

 * Time:2013.9.13

 * Result:

 * Memo:

 */

 

#include <cstring>

#include <cstdio>



#define INF 0x7fffffff

#define MAXT 1111



long m, n, s, t, f[MAXT], p2[MAXT], h[MAXT], sum[MAXT];



class Edge {

public:

	long v, f;

	Edge *op, *next;

	Edge() {}

	~Edge() {}

	Edge(long V, long F, Edge *o, Edge *ne) : v(V), f(F), op(o), next(ne) {}

} *g[MAXT], *now[MAXT], *p1[MAXT];



void add(long x, long y, long c) {

	g[x] = new Edge(y, c, 0, g[x]);

	g[y] = new Edge(x, 0, g[x], g[y]);

	g[x]->op = g[y];

}



long *l, *r, q[MAXT];

void SAP() {

	static char f;

	static Edge *e;

	static long i, ans, ww, w;

	memset(h, -1, sizeof h);

	memset(sum, 0, sizeof sum);

	l = r = q;

	*r++ = t;

	h[t] = 0;

	sum[0] = 1;

	while (l < r) {

		for (e = g[*l]; e; e = e->next)

			if (h[e->v] == -1) {

				++sum[h[e->v] = h[*l] + 1];

				*r++ = e->v;

			}

		++l;

	}

	for (i = 0; i <= t; ++i) {

		now[i] = g[i];

		p1[i] = 0;

		p2[i] = -1;

	}

	i = s;

	ans = 0;

	while (h[s] <= t) {

		f = 0;

		for (e = now[i]; e; e = e->next)

			if (e->f > 0 && h[i] == h[e->v] + 1) {

				now[i] = e;

				p1[e->v] = e;

				p2[e->v] = i;

				i = e->v;

				if (i == t) {

					ww = INF;

					for (w = t; w != s; w = p2[w])

						if (ww > p1[w]->f)

							ww = p1[w]->f;

					for (w = t; w != s; w = p2[w]) {

						p1[w]->f -= ww;

						p1[w]->op->f += ww;

					}

					ans += ww;

					i = s;

				}

				f = 1;

				break;

			}

		if (!f) {

			ww = t + 1;

			for (e = g[i]; e; e = e->next)

				if (e->f > 0 && ww > h[e->v]) {

					ww = h[e->v];

					now[i] = e;

				}

			++sum[ww > t ? ww : ++ww];

			if (!--sum[h[i]])

				break;

			h[i] = ww;

			if (i != s)

				i = p2[i];

		}

	}

	printf("%ld", ans);

}



int main() {

	static long i, j, k, A, B;



#ifndef ONLINE_JUDGE

	freopen("poj1149.in", "r", stdin);

	freopen("poj1149.out", "w", stdout);

#endif



	scanf("%ld%ld", &m, &n);

	s = 0;

	t = n + m + 1;

	for (i = 1; i <= m; ++i) {

		scanf("%ld", &A);

		add(s, i, A);

		f[i] = i;

	}

	for (i = 1; i <= n; ++i) {

		scanf("%ld", &A);

		for (j = 1; j <= A; ++j) {

			scanf("%ld", &k);

			add(f[k], i + m, INF);

			f[k] = i + m;

		}

		scanf("%ld", &B);

		add(i + m, t, B);

	}

	SAP();



	fclose(stdin);

	fclose(stdout);

	return 0;

}

 

 

你可能感兴趣的:(pig)