您的位置:首页 > 其它

hdu2444 The Accomodation of Students

2014-06-03 16:57 232 查看
PS: 二分图+最大匹配。 先判断是否为二分图同时对图进行染色,如果不是二分图输出No如果是二分图则将图分为左右两边的"标准二分图“,然后求解最大匹配

二分图没做几个题目, 就是凭着自己想着写的,代码不是很简洁。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int MAX = 210;

vector<int> G[MAX];
int n, m;
int color[MAX]; // 1 or -1

bool dfs(int v, int c) {
color[v] = c;
for(int i = 0; i < (int)G[v].size(); i++) {
int u = G[v][i];
if(color[u] == c) return false;
if(color[u] == 0 && !dfs(u, -c)) return false;
}
return true;
}

bool bipartite() {
for(int i = 1; i <= n; i++) {
if(color[i] == 0) {
if(!dfs(i, 1)) {
return false;
}
}
}
return true;
}

vector<int> g[MAX];
int from[MAX], tot;
int use[MAX];

int Match(int x) {
for(int i = 0; i < (int)g[x].size(); i++) {
int u = g[x][i];
if(!use[u]) {
use[u] = true;
if(from[u]==-1 || Match(from[u])) {
from[u] = x;
return true;
}
}
}
return false;
}

int hungary() {
tot = 0;
memset(from, 255, sizeof(from));
for(int i = 1; i <= n; i++) {
if(color[i]==1) {
memset(use, 0, sizeof(use));
if(Match(i)) {
++tot;
}
}
}
return tot;
}

void build_map() {
for(int i = 1; i <= n; i++) g[i].clear();
for(int i = 1; i <= n; i++) {
if(color[i]==1) {
for(int j = 0; j < (int)G[i].size(); j++) {
int &u = G[i][j];
g[i].push_back(u);
}
}
}
}

int main()
{
while(scanf("%d%d", &n, &m) != EOF) {
memset(color, 0, sizeof(color));
int x, y;
for(int i = 1; i <= 205; i++) G[i].clear();
for(int i = 1; i <= m; i++) {
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
bool ok = bipartite();
if(!ok) {
printf("No\n");
continue;
} else {
build_map();
int res = hungary();
printf("%d\n", res);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: