poj1904 完美匹配+Tarjan

King‘s Quest

Time Limit: 15000MS   Memory Limit: 65536K
Total Submissions: 9460   Accepted: 3497
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题解这里
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=4080;
const int M=4e6+88;
vector<int>sc[N];
vector<int>G[N];
int head[N],dfn[N],low[N],q[N];
bool instack[N],mp[2008][2008];
int tot,scnt,l,cnt;
struct node
{
    int to,next;
} e[M];
void add(int u,int v)
{
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
void Tarjan(int u)
{
    dfn[u]=low[u]=++cnt;
    q[l++]=u;
    instack[u]=1;
    for(int i=head[u]; ~i; i=e[i].next)
    {
        int v=e[i].to;
        if(!dfn[v])
        {
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v]&&dfn[v]<low[u]) low[u]=dfn[v];
    }
    if(low[u]==dfn[u])
    {
        ++scnt;
        int t;
        do
        {
            t=q[--l];
            sc[scnt].push_back(t);
            instack[t]=0;
        }
        while(t!=u);
    }
}
int main()
{
    int n,x,y;
    while(scanf("%d",&n)!=EOF)
    {
        tot=scnt=cnt=l=0;
        memset(head,-1,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(mp,0,sizeof(mp));
        for(int i=1; i<=n; ++i)
        {
            scanf("%d",&x);
            while(x--)
            {
                scanf("%d",&y);
                add(i,y+n);
                G[i].clear();
                sc[i].clear();
                mp[i][y]=1;
            }
        }
        for(int i=1; i<=n; ++i)
        {
            scanf("%d",&x);
            add(x+n,i);
        }
        for(int i=1; i<=n; ++i) if(!dfn[i]) Tarjan(i);
        for(int i=1; i<=scnt; ++i) sort(sc[i].begin(),sc[i].end());
        for(int i=1; i<=scnt; ++i)
        {
            int tc=upper_bound(sc[i].begin(),sc[i].end(),n)-sc[i].begin();
            for(int j=0; j<tc; ++j) for(int k=tc; k<(int)sc[i].size(); ++k) if(mp[sc[i][j]][sc[i][k]-n] ) G[sc[i][j]].push_back(sc[i][k]-n);
        }
        for(int i=1; i<=n; ++i)
        {
            printf("%d",(int)G[i].size());
            for(int j=0; j<(int)G[i].size(); ++j) printf(" %d",G[i][j]);
            puts("");
        }
    }
}
时间: 2024-07-30 09:58:04

poj1904 完美匹配+Tarjan的相关文章

HDU4685 Prince and Princess 完美匹配+强连通

题意:现在有n个王子,m个公主.现在要给他们配对,王子会和他喜欢的一个人结婚,而公主不能做选择. 这题啃得好费劲,有个类似的题目poj1904,那个题目也是给王子与公主配对,但那个是王子公主各n个,且给定了一个完美匹配,然后求每个王子可以做出的选择且不影响最大匹配数目.那题是先建各条喜欢关系的边,然后在由被选择的公主连一条边到与之配对的王子,强连通之后如果一个王子和一个公主在一个强连通分量中,那么他们结合的话,他们的另一半也各自能在强连通中找到另外的匹配,就是符合题意的结果了. 这个题目算是升级

poj1904 二分图匹配+强连通分量

http://poj.org/problem?id=1904 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 you

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

”乳罩图“ 的完美匹配:高温展开与顶点膨胀技巧

本文的目的是通过一个例子来介绍统计力学中精确可解模型的两个经典方法:高温展开和顶点膨胀. 问题是这样的:考虑这样一张非常类似 "bra" 的图: 注意这个图不是平面图!上面两条实线的边与下面两条实线的边分别是粘在一起的,左边两条实线的边和右边的两条实线的边也是分别粘合的:虚线部分不是边,只是用来描述粘合定向的.因此这个图的每个顶点的度数都是 3. 想象它的立体图:这是一个乳罩,已经穿戴在某个美女身上,则上下和左右的实线边相当于系的绳子. 问这个图有多少不同的完美匹配? 答案是 $64$

HDU 1533 Going Home(KM完美匹配)

HDU 1533 Going Home 题目链接 题意:就是一个H要对应一个m,使得总曼哈顿距离最小 思路:KM完美匹配,由于是要最小,所以边权建负数来处理即可 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAXNODE = 105; typedef int Type; const T

HDU_2255 二分图最佳完美匹配 KM匈牙利算法

一开始还没看懂这个算法,后来看了陶叔去年的PPT的实例演示才弄懂 用一个lx[]和ly[]来记录X和Y集合中点的权值,有个定理是 lx[i]+ly[j]==w[i][j](边权值) 则该点是最佳匹配,因为首先 那个不等式肯定要>=的,否则就不满足题意了,如果是>则可以去匹配更有价值的边或者把权值降下来让匹配边的潜力更大. 所以只有把握了这个条件,其他就是走一遍最大匹配数.以及up()函数用来在无法匹配的时候,进行其他点的权值降低(也可以说是增广路的搜索)来得到匹配. #include <

(转)二分图的最大匹配、完美匹配和匈牙利算法

转载自http://www.renfei.org/blog/bipartite-matching.html 二分图的最大匹配.完美匹配和匈牙利算法 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是

二分图的最大匹配、完美匹配和匈牙利算法(转)

转载自:http://blog.csdn.net/pi9nc/article/details/11848327 二分图的最大匹配.完美匹配和匈牙利算法 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这

codevs 1222 信与信封问题(二分图的完美匹配)

1222 信与信封问题 题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封.不幸的是,Small John无法将拿出的信正确地装回信封中了. 将Small John所提供的n封信依次编号为1,2,…,n:且n个信封也依次编号为1,2,…,n.假定Small John能提供一组信息:第i封信肯定不是装在信封j中.请编程帮助Small John,尽可能多地将信正确地装回信封. 输入