Luo Gu · [24 network flow problem] test database problem

~ Ann is here shown signs of portal: Luo Gu P2763 test database problem

answer

Each topic has its own type, but because the total number of questions is equal to the number of items of each type and so in the end it if you want to be out on paper can only select a type , and each type has housed the subject of quantitative restrictions. This is relatively easy to build FIG bar, S is connected to each of the questions, a capacity of 1, each connected to a T type, capacity numbers corresponding questions. Title and the corresponding type should be connected INF [1] side of the line capacity, the maximum running flow can be matched.

But the focus of this question should be output scheme. Program is very simple, for each type of point to enumerate it even edge topics that is when we build [map] back side of the stream, if there is traffic on this side, then this edge is matched, so the subject is the income came in.

Of course, the number of each type split into a plurality of points required subject then so hard core should run bipartite graph matching is required. [Hu mouth, not really

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define maxn 5005
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int read() {
	int x = 0, f = 1, ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
	return x * f;
}

struct edge {int to, w, nxt;} e[200005];
int head[maxn], k = 0;
void add(int u, int v, int w) {
	e[k] = {v, w, head[u]}; head[u] = k++;
	e[k] = {u, 0, head[v]}; head[v] = k++;
}

int d[maxn], S, T;
queue<int> q;
bool bfs() {
	memset(d, 0, sizeof d); while(q.size()) q.pop();
	q.push(S); d[S] = 1;
	while(q.size()) {
		register int u = q.front(), v; q.pop(); 
		for(int i = head[u]; ~i; i = e[i].nxt) {
			v = e[i].to;
			if(e[i].w && !d[v]) {
				q.push(v), d[v] = d[u] + 1;
				if(v == T) return true;
			}
		}
	}
	return false;
}

int Dinic(int u, int flow) {
	if(u == T) return flow;
	register int rest = flow, k;
	for(int i = head[u], v; ~i && rest; i = e[i].nxt) {
		v = e[i].to; 
		if(e[i].w && d[v] == d[u] + 1) {
			k = Dinic(v, min(rest, e[i].w));
			if(!k) d[v] = 0;
			e[i].w -= k, e[i ^ 1].w += k;
			rest -= k;
		}
	}
	return flow - rest;
}//上面是最大流模板

int m, n, sum = 0;
signed main() {
	memset(head, -1, sizeof head);
	m = read(), n = read(); S = 0, T = n + m + 1;
	for(int i = 1, x; i <= m; i++) x = read(), add(i + n, T, x), sum += x;
	for(int i = 1, x, y; i <= n; i++) {
		add(S, i, 1); x = read();
		while(x--) y = read(), add(i, y + n, INF);//如上文建图
	}
	
	register int flow = 0, ans = 0;
	while(bfs()) while(flow = Dinic(S, INF)) ans += flow;
	if(ans != sum) {puts("No Solution!"); return 0;}
	printf("ans = %d\n", ans);
	for(int u = n + 1; u <= n + m; u++) {
		printf("%d:", u - n);
		for(int i = head[u], v; ~i; i = e[i].nxt) {//看每个类型对应的题目
			v = e[i].to; if(e[i].w && v <= n) printf(" %d", v);
		}//SPJ下题目顺序无所谓的
		puts("");
	}
	return 0;
}

Currently he wrote several network flows are still relatively simple ah.

Meet the assessment :)

——End——
 

Published 158 original articles · won praise 23 · views 20000 +

Guess you like

Origin blog.csdn.net/qq_43326267/article/details/104189276