【连通图|二分匹配+强连通分量】POJ-1904 King's Quest

King’s Quest

Time Limit: 15000MS Memory Limit: 65536K

Case Time Limit: 2000MS

Description

Once upon a time there lived a king and he had N sons. And there were N beautiful girls in the kingdom and the king knew about each of his sons which of those girls he did like. The sons of the king were young and light-headed, so it was possible for one son to like several girls.

So the king asked his wizard to find for each of his sons the girl he liked, so that he could marry her. And the king’s wizard did it – for each son the girl that he could marry was chosen, so that he liked this girl and, of course, each beautiful girl had to marry only one of the king’s sons.

However, the king looked at the list and said: “I like the list you have made, but I am not completely satisfied. For each son I would like to know all the girls that he can marry. Of course, after he marries any of those girls, for each other son you must still be able to choose the girl he likes to marry.”

The problem the king wanted the wizard to solve had become too hard for him. You must save wizard’s head by solving this problem.

Input

The first line of the input contains N – the number of king’s sons (1 <= N <= 2000). Next N lines for each of king’s sons contain the list of the girls he likes: first Ki – the number of those girls, and then Ki different integer numbers, ranging from 1 to N denoting the girls. The sum of all Ki does not exceed 200000.

The last line of the case contains the original list the wizard had made – N different integer numbers: for each son the number of the girl he would marry in compliance with this list. It is guaranteed that the list is correct, that is, each son likes the girl he must marry according to this list.

Output

Output N lines.For each king’s son first print Li – the number of different girls he likes and can marry so that after his marriage it is possible to marry each of the other king’s sons. After that print Li different integer numbers denoting those girls, in ascending order.

Sample Input

4

2 1 2

2 1 2

2 2 3

2 3 4

1 2 3 4

Sample Output

2 1 2

2 1 2

1 3

1 4

Hint

This problem has huge input and output data,use scanf() and printf() instead of cin and cout to read data to avoid time limit exceed.

Source

Northeastern Europe 2003



题意: 给出一个二分图以及其中一个完备匹配,求对于每个X点,所有可以与之匹配的Y点,使得最终仍然能得到一个完备匹配。

思路:

你可以参考这儿:Polla 分析的很不错。

刚看到这题会往二分图匹配上想(虽然我直接就去看什么是稳定婚姻问题了,但是该题和稳定婚姻没有什么关系)。如果忽略给出的那个完备匹配的话,可以枚举所有的Y点与X匹配,之后进行二分匹配的判定。但是复杂度太高,势必TLE。

给出的完备匹配一定包含了一些有用信息。既然X的信息全部在输入数据中给出了,那么完备匹配一定包含了一些关于Y的信息。有些X点是绝对不能和Y点在一起的,例如样例中3号王子和2号女孩一定不能在一起,因为这样的话,1号王子和2号王子势必有一个人单身。那么完备匹配给出的信息就是“每个Y点可以喜欢的X点”。虽然没有给全,但是一个足矣。

X点向喜欢的Y点连有向边,再将给出的完备匹配中的Y点向X点也连上有向边。假定给出的完备匹配是所有的Xi和Yi匹配,那么假如Xi和Yj匹配,Yi和Xj势必寻找另外的伴侣,设想Xi和Yj处于同一个强连通分量当中,强连通分量一定包含一个环,那么Xj和Yi一定是能找到另外的伴侣的。

那么是不是说,只要给出一组完备匹配,其他所有的完备匹配的方案都和它处于同一个强连通分量当中呢?

我觉得这样说应该是没有错的。所有完备匹配方案之间应该是有一些共同的信息的。那就是一定成环。

P.S. 如果采用输出输出外挂,G++评测可以500+ms。但是IO外挂对于C++评测是无效的。

代码如下:

/*
 * ID: j.sure.1
 * PROG:
 * LANG: C++
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <climits>
#include <iostream>
#define PB push_back
#define LL long long
using namespace std;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
/****************************************/
const int N = 4444, M = 222222;
int n, tot, scc_cnt, deep;
int head[N], dfn[N], scc_id[N];
struct Edge {
    int v, next;
    Edge(){}
    Edge(int _v, int _next):
        v(_v), next(_next){}
}e[M];
stack <int> s;
vector<int> ans;

void init()
{
    tot = deep = scc_cnt = 0;
    memset(head, -1, sizeof(head));
    memset(dfn, 0, sizeof(dfn));
    memset(scc_id, 0, sizeof(scc_id));
}

void add(int u, int v)
{
    e[tot] = Edge(v, head[u]);
    head[u] = tot++;
}

int dfs(int u)
{
    int lowu = dfn[u] = ++deep;
    s.push(u);
    for(int i = head[u]; ~i; i = e[i].next) {
        int v = e[i].v;
        if(!dfn[v]) {
            int lowv = dfs(v);
            lowu = min(lowu, lowv);
        }
        else if(!scc_id[v]) {
            lowu = min(lowu, dfn[v]);
        }
    }
    if(lowu == dfn[u]) {
        scc_cnt++;
        while(1) {
            int x= s.top(); s.pop();
            scc_id[x] = scc_cnt;
            if(x == u) break;
        }
    }
    return lowu;
}

void tarjan()
{
    for(int i = 1; i <= 2*n; i++) {
        if(!dfn[i]) dfs(i);
    }
}

int main()
{
#ifdef J_Sure
    freopen("000.in", "r", stdin);
    //freopen("999.out", "w", stdout);
#endif
    while(~scanf("%d", &n)) {
        int m, j;
        init();
        for(int i = 1; i <= n; i++) {
            scanf("%d", &m);
            while(m--) {
                scanf("%d", &j);
                add(i, j+n);
            }
        }
        for(int i = 1; i <= n; i++) {
            scanf("%d", &j);
            add(j+n, i);
        }
        tarjan();
        for(int u = 1; u <= n; u++) {
            ans.clear();
            for(int i = head[u]; ~i; i = e[i].next) {
                int v = e[i].v;
                if(scc_id[u] == scc_id[v]) ans.PB(v-n);
            }
            size_t len = ans.size();
            printf("%d", (int)len);
            sort(ans.begin(), ans.end());
            for(size_t k = 0; k < len; k++) {
                printf(" %d", ans[k]);
            }
            puts("");
        }
    }
    return 0;
}

【连通图|二分匹配+强连通分量】POJ-1904 King's Quest

时间: 2024-10-09 03:28:36

【连通图|二分匹配+强连通分量】POJ-1904 King's Quest的相关文章

POJ - 1904 King&#39;s Quest(强连通分量+二分图匹配)

题目大意:有N个帅哥和N个美女,现在给出每个帅哥所喜欢的美女的编号,和一个帅哥和美女的完美匹配 问每个帅哥可以娶多少个美女,且当他娶完这个美女后,剩下的人还可以完美匹配 解题思路:神题啊,给一个大神的详细解答 具体是这样的,首先先建边,把帅哥和能娶到的美女连边,再把完美匹配的美女和帅哥连边,这样就形成了一张有向图了 接着,找出这张有向图的所有强连通分量,在强连通分量里面的帅哥都可以娶到自己喜欢的美女,且娶完这个美女后,不会影响到其他人 为什么呢? 假设xi为帅哥,yi和yj为美女,假设给定的完美

POJ 1904 King&#39;s Quest强连通分量+二分图完美匹配

题目描述: Description Once upon a time there lived a king and he had N sons. And there were N beautiful girls in the kingdom and the king knew about each of his sons which of those girls he did like. The sons of the king were young and light-headed, so i

Poj 1904 King&#39;s Quest 强连通分量

题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可以取哪些公主,并且保证取了一个公主后,全局还是存在完美匹配. 题解: 1.建图: 如果王子u对公主v心仪,则连一条边u->v.在样例给出的那组完美匹配中,如果王子u娶了公主v,连一条边v->u. 2.求强连通分量: 如果王子和自己心仪的公主属于同一个强连通分量,那么王子就可以娶这个公主. 1 #i

POJ 1904 King&#39;s Quest 强连通分量+二分图增广判定

http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <stack> #include <ve

POJ 1904 King&#39;s Quest(强连通)

POJ 1904 King's Quest 题目链接 题意:n个男人,每个人都有一个喜欢的女人列表,现在给一个完美匹配,问所有完美匹配中,每个人可能娶到的女人列表 思路:强连通,建图,男的连一条边指向女,然后完美匹配的边女的指向男,然后求强连通,在同一个强连通分支并且是自己想娶的的就可能娶到 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #inc

poj 1904 King&#39;s Quest

King's Quest 题意:有N个王子和N个妹子;(1 <= N <= 2000)第i个王子喜欢Ki个妹子:(详见sample)题给一个完美匹配,即每一个王子和喜欢的一个妹子结婚:问每一个王子可以有几种选择(在自己喜欢的妹子里面选),并输出可选的妹子的标号(升序): Sample Input 4 (N) 2 1 2 (Ki) 2 1 2 2 2 3 2 3 4 1 2 3 4 (完美匹配) Sample Output 2 1 2 2 1 2 1 3 1 4 分析:图匹配问题,1~N为王子的

【建模+强连通分量】POJ1904 King&#39;s Quest

Description 一个国王有n个王子,同时有n个女孩.每个王子都有自己喜欢的若干个女孩,现给定一个合法的完备匹配(也就是一个王子娶其中一个自己喜欢女孩),求每个王子可以选择哪些女孩可以让剩下的每个王子依旧能够选择到自己喜欢的一个女孩. Solution 对于给定的排列,我们设ai为男a对应的女生,bi为女b对应的男生. 男i可以选哪些女生?选ai显然是可以的,如果没有选ai而选的x,那么会造成两个影响,x有两个a和bx选,ai没有人选. 所以需要让bx选新的女生,如果bx能选到ai,那么问

H - Prince and Princess - HDU 4685(二分匹配+强连通分量)

题意:有N个王子M个公主,王子喜欢一些公主,而且只能是王子喜欢的人,他们才可以结婚,现在让他们尽可能多的结婚的前提下找出来每个王子都可以和谁结婚. 分析:先求出来他们的最大匹配,因为给的数据未必是完备匹配,所以需要添加一些点使他们成为完备匹配才能求出来的环是完整的,比如第二组数据: 1 2   2 1 2 如果不添加虚拟点做成匹配,只会匹配成功一个,这样就找不出来环了,所以需要添加虚拟的王子和公主,虚拟的王子喜欢所有的公主,虚拟的公主被所有的王子喜欢,注意都是王子喜欢公主的,公主没有选择喜欢的权

hdu 4685 二分匹配+强连通分量

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 题解: 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<vector> 5 #include<stack> 6 #include<algorithm> 7 using namespace std; 8 9 const int maxn =