[HDOJ1054]Strategic Game(最小点覆盖,最大二分匹配,HK算法)
2016-08-25 13:59
567 查看
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1054
题意:给一棵树,选几个节点,使得这个节点相连的所有边都能被走到。求最少的点数。
这就是最小点覆盖的原始定义,根据König定理,最小点覆盖=最大匹配数可求。应该是点太稀疏了,用邻接矩阵的匈牙利会TLE。。
题意:给一棵树,选几个节点,使得这个节点相连的所有边都能被走到。求最少的点数。
这就是最小点覆盖的原始定义,根据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; }
相关文章推荐
- hdoj1054 Strategic Game(二分图最大匹配求最小点覆盖)
- hdu 1054 Strategic Game(模板) 最大二分匹配,最小点覆盖 匈牙利算法
- hdu 1054 Strategic Game 最小顶点覆盖(二分图最大匹配)
- hdu 1054 Strategic Game 最小顶点覆盖(二分图最大匹配)
- HDU 1054 Strategic Game-二分匹配&最小顶点覆盖
- HDOJ 1498 —— 50 years, 50 colors 二分图匹配(最小点覆盖 = 最大二分匹配)
- HDOJ---1054 Strategic Game[求最小顶点覆盖-无向图]
- HDU 1151Air Raid 最小路径覆盖=n-最大匹配量 (第二道二分匹配)
- poj 2594 Treasure Exploration(最小路径覆盖/二分最大匹配)
- HDU 1151Air Raid 最小路径覆盖=n-最大匹配量 (第二道二分匹配)
- 为什么二分图的最大二分匹配数等于最小点覆盖数
- POJ 3020 最小路径覆盖 = 顶点数-最大匹配数 二分匹配
- HDU 4160 最小路径覆盖 = 顶点数 - 最大匹配数 二分匹配
- hdoj 1054 Strategic Game【匈牙利算法+最小顶点覆盖】
- poj3020 匈牙利算法+公式:二分无向图的最小路径覆盖 = 顶点数 - 最大二分匹配数 / 2
- HDU 1151Air Raid 最小路径覆盖=n-最大匹配量 (第二道二分匹配)
- uva11419 【最大二分匹配求最小点覆盖 匈牙利算法】
- HDOJ 题目1054 Strategic Game(二分图最大匹配)
- UVa live6492Welcome Party(二分最大匹配之最小点覆盖)
- UVA 11419 SAM I AM(最大二分匹配&最小点覆盖:König定理)