HDU-2444(二分图判断与匹配)

#pragma warning (disable : 4996)
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 2e2 + 10;
struct node {
	int to, nxt;
}edge[maxn * 100];

int head[maxn], col[maxn], match[maxn], vis[maxn];

int ecnt = 0;
void addedge(int u, int v) {//邻接表比vector快
	edge[ecnt].to = v;
	edge[ecnt].nxt = head[u];
	head[u] = ecnt++;
}

bool bfs(int s) {//染色 判断二分图
	memset(col, 0, sizeof col);
	queue<int> q;
	col[s] = 1;
	q.push(s);
	while (!q.empty()) {
		s = q.front();
		q.pop();
		for (int i = head[s]; i + 1; i = edge[i].nxt) {
			if (col[edge[i].to] == 0)
				col[edge[i].to] = -col[s], q.push(edge[i].to);
			if (col[edge[i].to] == col[s])
				return false;
		}
	}
	return true;
}

bool dfs(int s) {//匈牙利算法
	for (int i = head[s]; i + 1; i = edge[i].nxt) {
		if (vis[edge[i].to] == false) {
			vis[edge[i].to] = true;
			if (match[edge[i].to] == 0 || dfs(match[edge[i].to])) {
				match[edge[i].to] = s;
				//match[s] = edge[i].to;
				return true;
			}
		}
	}
	return false;
}


int main() {
	int n, m;
	while (scanf("%d%d", &n, &m) != EOF) {
		memset(match, 0, sizeof(match));
		memset(head, -1, sizeof head);//必须是-1, 0 会干扰答案
		ecnt = 0;
		for (int i = 1; i <= m; i++) {
			int a, b;
			scanf("%d%d", &a, &b);
			addedge(a, b);
			//addedge(b, a); //一样的,建双向边就要 ans /= 2 
		}
		if (!bfs(1)) {
			puts("No");
		}
		else {
			int sum = 0;
			for (int i = 1; i <= n; i++) {
				memset(vis, false, sizeof(vis));
				if (dfs(i)) {
					sum++;
				}
			}
			printf("%d\n", sum);
		}
	}
	return 0;
}
#pragma warning (disable : 4996)
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int maxn =2e2+10;

int col[maxn], match[maxn], vis[maxn];

vector<int> v[maxn];//邻接矩阵存图
bool bfs(int s) {//染色 判断二分图
	memset(col, 0, sizeof col);
	queue<int> q;
	col[s] = 1;
	q.push(s);
	while (!q.empty()) {
		s = q.front();
		q.pop();
		int len = v[s].size();
		for (int i = 0; i < len; ++i) {
			if (col[v[s][i]] == 0)
				col[v[s][i]] = -col[s], q.push(v[s][i]);
			if (col[v[s][i]] == col[s])
				return false;
		}
	}
	return true;
}

bool dfs(int s) {
	int len = v[s].size();
	for (int i = 0; i < len; ++i) {
		if (vis[v[s][i]] == false) {
			vis[v[s][i]] = true;
			if (match[v[s][i]] == 0 || dfs(match[v[s][i]])) {
				match[v[s][i]] = s;
				//match[s] = v[s][i];//建双向边的时候就不要这个了//一般好像也不需要,似乎是多余的东西
				return true;
			}
		}
	}
	return false;
}

int main() {
	int n, m;
	while (scanf("%d%d", &n, &m) != EOF) {
		memset(match, 0, sizeof(match));
		for (int i = 0; i <= n; ++i) {
			v[i].clear();
		}
		for (int i = 1; i <= m; i++) {
			int a, b;
			scanf("%d%d", &a, &b);
			v[a].push_back(b);
			v[b].push_back(a);//建无向图 答案就要 ans/=2
		}
		if (!bfs(1)) {
			puts("No");
		}
		else {
			int sum = 0;
			for (int i = 1; i <= n; i++) {
				memset(vis, false, sizeof(vis));
				if (dfs(i)) {
					sum++;
				}
			}
			printf("%d\n", sum/2);
		}
	}
	return 0;
}

posted @ 2020-08-03 23:13  wansheking  阅读(88)  评论(0)    收藏  举报