FIG smallest coverage POJ1325 bipartite

Topic connection  http://poj.org/problem?id=1325

Subject to the effect:

Two machines A, B, and K tasks.

A machine has N different modes (Mode 0 ~ N-1), the machine B has M different modes (Mode 0 ~ M-1).

Both machines are at the beginning 0 mode.

Each task may be performed either on A, it can also be performed on the B.

For each task i, given two integers a [i] and b [i], if expressed in the execution of the task A, needs to set the mode to a [i], if executed on B, need to model b [ i].

Tasks can be performed in any order, but each machine will restart mode conversion once again.

Seeking how to allocate tasks and rationalize the order, the machine can restart the minimum number of times .

Ideas:

For a task model may be a [i] do in A or B mode to b [i] to do, but only one made on the line. Can be abstracted into a side, two end sides is a [i] and b [i], to satisfy the only to have a point. For A and B can be considered as the two parts of the bipartite graph, the edge is an edge in the bipartite graph, there is a meet point, points corresponding to two sides of bipartite graph can have a covered, it can be seen that It is the smallest coverage of a bipartite graph. Minimum Covering direct enough.

= Minimum coverage maximum matching. Hungary direct algorithm for maximum matching can be.

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#define mem(a, b) memset(a, b, sizeof a)
using namespace std;
const int N = 2010;
int head[N], nex[N], to[N];
int cnt, n, m, k;
int match[1100];
bool vis[1100];
inline void add(int x, int y){
	++cnt;
	to[cnt] = y;
	nex[cnt] = head[x];
	head[x] = cnt;
}
bool dfs(int x){
	for (int i = head[x]; i != -1; i = nex[i]){
		int y = to[i];
		if (vis[y])continue;
		vis[y] = 1;
		if (match[y] == -1 || dfs(match[y])){
			match[y] = x;
			return 1;
		}
	}
	return 0;
}
int solve(){
	int ans = 0;
	for (int i = 0; i < n; i++){
		mem(vis, 0);
		if (dfs(i))ans++;
	}
	return ans;
}
int main()
{
	while (~scanf("%d", &n) && n){
		mem(match, -1);
		mem(head, -1);
		mem(nex, -1);
		cnt = 0;
		scanf("%d %d", &m, &k);
		for (int i = 0; i < k; i++){
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			if (y && z){
				add(y, z + 110);
				add(z + 110, y);
			}
		}
		printf("%d\n", solve());
	}
	return 0;
}

 

Published 204 original articles · won praise 13 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_43701790/article/details/104592729