标签:
题目大意:有N个帅哥和N个美女,现在给出每个帅哥所喜欢的美女的编号,和一个帅哥和美女的完美匹配
问每个帅哥可以娶多少个美女,且当他娶完这个美女后,剩下的人还可以完美匹配
解题思路:神题啊,给一个大神的详细解答
具体是这样的,首先先建边,把帅哥和能娶到的美女连边,再把完美匹配的美女和帅哥连边,这样就形成了一张有向图了
接着,找出这张有向图的所有强连通分量,在强连通分量里面的帅哥都可以娶到自己喜欢的美女,且娶完这个美女后,不会影响到其他人
为什么呢?
假设xi为帅哥,yi和yj为美女,假设给定的完美匹配中xi和yi匹配。
现在,我们想让xi和yj匹配,按照二分图匹配,先要找到一条增广链
因为要完美匹配,所以这条增广链最后肯定会指向yi的,那如果把yi再连向xi,是不是就形成了一个环了,那这个环肯定是一个强连通分量了。
所以说,如果xi可以选择yj,那么xi和yj必定是在同一个连通分量里面了
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define N 4010
#define M 1000010
#define S 2010
#define min(a,b) ((a)<(b) ? (a) : (b))
#define max(a,b) ((a)>(b) ? (a) : (b))
struct Edge{
int from, to, next;
}E[M];
int pre[N], sccno[N], stack[N], lowlink[N], head[N];
int n, m, dfs_clock, scc_cnt, top, tot;
int love[S][S];
void dfs(int u) {
pre[u] = lowlink[u] = ++dfs_clock;
stack[++top] = u;
int v;
for (int i = head[u]; i != -1; i = E[i].next) {
v = E[i].to;
if (!pre[v]) {
dfs(v);
lowlink[u] = min(lowlink[u], lowlink[v]);
}
else if (!sccno[v]) {
lowlink[u] = min(lowlink[u], pre[v]);
}
}
if (lowlink[u] == pre[u]) {
scc_cnt++;
while (1) {
v = stack[top--];
sccno[v] = scc_cnt;
if (v == u)
break;
}
}
}
vector<int> v[N];
void solve() {
memset(pre, 0, sizeof(pre));
memset(sccno, 0, sizeof(sccno));
dfs_clock = scc_cnt = top = 0;
for (int i = 0; i < 2 * n; i++)
if (!pre[i])
dfs(i);
for (int i = 0; i < n; i++)
v[i].clear();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (sccno[i] == sccno[j + n] && love[i][j])
v[i].push_back(j + 1);
}
printf("%d", v[i].size());
for (int j = 0; j < v[i].size(); j++)
printf(" %d", v[i][j]);
printf("\n");
}
}
void AddEdge(int u, int v) {
E[tot].from = u;
E[tot].to =v;
E[tot].next = head[u];
head[u] = tot++;
}
void init() {
memset(head, -1, sizeof(head));
memset(love, 0, sizeof(love));
tot = 0;
int t, u, v;
for (u = 0; u < n; u++) {
scanf("%d", &t);
while (t--) {
scanf("%d", &v);
love[u][v - 1] = true;
AddEdge(u, v + n - 1);
}
}
for (int i = 0; i < n; i++) {
scanf("%d", &v);
AddEdge(v - 1 + n, i);
}
}
int main() {
while (scanf("%d", &n) != EOF) {
init();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ - 1904 King's Quest(强连通分量+二分图匹配)
标签:
原文地址:http://blog.csdn.net/l123012013048/article/details/47690005