您的位置:首页 > 其它

[HDOJ1054]Strategic Game(最小点覆盖,最大二分匹配,HK算法)

2016-08-25 13:59 567 查看
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1054

题意:给一棵树,选几个节点,使得这个节点相连的所有边都能被走到。求最少的点数。

这就是最小点覆盖的原始定义,根据König定理,最小点覆盖=最大匹配数可求。应该是点太稀疏了,用邻接矩阵的匈牙利会TLE。。

/*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f7f, sizeof(a))
#define lrt rt << 1
#define rrt rt << 1 | 1
#define pi 3.14159265359
#define RT return
#define lowbit(x) x & (-x)
#define onecnt(x) __builtin_popcount(x)
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef pair<LL, LL> pll;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb;

const int maxn = 1530;
const int inf = 0x3f3f3f3f;
int n;
int nx, ny, dist;
int Mx[maxn], My[maxn], dx[maxn], dy[maxn], vis[maxn], G[maxn][maxn];

bool dfs(int u){
for(int v = 0; v < ny; v++)
if(!vis[v] && G[u][v] && dy[v] == dx[u] + 1){
vis[v] = 1;
if(My[v] != -1 && dy[v] == dist)
continue;
if(My[v] == -1|| dfs(My[v])){
My[v] = u;
Mx[u] = v;
return 1;
}
}
return 0;
}
bool bfs(){
queue<int> Q;
dist = inf;
memset(dx, -1, sizeof(dx));
memset(dy, -1, sizeof(dy));
for(int i = 0; i < nx; i++)
if(Mx[i] == -1){
Q.push(i);
dx[i] = 0;
}
while(!Q.empty()){
int u = Q.front();
Q.pop();
if(dx[u] > dist)
break;
for(int v = 0; v < ny; v++)
if(G[u][v] && dy[v] == -1){
dy[v] = dx[u] + 1;
if(My[v] == -1)
dist = dy[v];
else{
dx[My[v]] = dy[v] + 1;
Q.push(My[v]);
}
}
}
return dist != inf;
}
int hk() {
int res = 0;
memset(Mx, -1, sizeof(Mx));
memset(My, -1, sizeof(My));
while(bfs()){
memset(vis, 0, sizeof(vis));
for(int i = 0; i < nx; i++)
if(Mx[i] == -1&& dfs(i))
res++;
}
return res;
}

int main() {
// FRead();
int u, v, k;
while(~Rint(n)) {
nx = ny = n; Cls(G);
Rep(i, n) {
scanf("%d:(%d)", &u, &k);
Rep(i, k) {
Rint(v);
G[u][v] = G[v][u] = 1;
}
}
printf("%d\n", hk()/2);
}
RT 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: