题意:n个王子有自己喜欢的ki个公主,有n个公主,每个王子只能娶一个自己喜欢的公主且不能绿别的王子。现在给你一种王子娶公主的方案,并且保证这种方案是正确的。请你给出,每个王子能娶哪些公主,要求娶这些公主时,其他王子也能娶到公主。

思路:还以为是完全匹配,直接暴力匹配显然TLE了。正解是缩点...我们把每个王子指向自己喜欢的公主们,然后把给定的方案中的公主指向自己嫁给的王子,然后缩点,同一个点中王子喜欢的公主都能娶。因为每个王子指向的肯定都是公主(至少两个),公主指向的肯定都是王子,所以想要形成一个强连通图这个图中王子公主数量肯定是相同的,那么假如王子选择一个自己喜欢的公主,那么这个图中的其他的王子可以选择其他的公主,显然肯定能完全匹配。

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
int head[maxn], ans[maxn], tot;
struct Edge{
int to, next;
}edge[maxn * maxn];
int low[maxn], dfn[maxn], Stack[maxn], belong[maxn];
int index, top, scc;
bool instack[maxn];
void addEdge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void tarjan(int u){
int v;
low[u] = dfn[u] = ++index;
Stack[top++] = u;
instack[u] = true;
for(int i = head[u]; i != -; i = edge[i].next){
v = edge[i].to;
if(!dfn[v]){
tarjan(v);
if(low[u] > low[v]) low[u] = low[v];
}
else if(instack[v] && low[u] > dfn[v]){
low[u] = dfn[v];
}
}
if(low[u] == dfn[u]){
scc++;
do{
v = Stack[--top];
instack[v] = false;
belong[v] = scc;
}while(v != u);
}
}
void solve(int n){
memset(dfn, , sizeof(dfn));
memset(instack, false, sizeof(instack));
index = scc = top = ;
for(int i = ; i <= n; i++){
if(!dfn[i])
tarjan(i);
}
}
void init(){
tot = ;
memset(head, -, sizeof(head));
}
int main(){
int n;
while(~scanf("%d", &n)){
int k, tmp;
init();
for(int i = ; i <= n; i++){
scanf("%d", &k);
while(k--){
scanf("%d", &tmp);
addEdge(i, tmp + n);
}
}
for(int i = ; i <= n; i++){
scanf("%d", &tmp);
addEdge(tmp + n, i);
}
solve( * n);
int ret;
for(int u = ; u <= n; u++){
ret = ;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(belong[v] == belong[u]){
ans[ret++] = v - n;
}
}
sort(ans, ans + ret);
printf("%d", ret);
for(int i = ; i < ret; i++){
printf(" %d", ans[i]);
}
printf("\n");
}
}
return ;
}

POJ 1904 King's Quest(强连通图)题解的更多相关文章

  1. POJ 1904 King's Quest tarjan

    King's Quest 题目连接: http://poj.org/problem?id=1904 Description Once upon a time there lived a king an ...

  2. poj 1904 King's Quest

    King's Quest 题意:有N个王子和N个妹子;(1 <= N <= 2000)第i个王子喜欢Ki个妹子:(详见sample)题给一个完美匹配,即每一个王子和喜欢的一个妹子结婚:问每 ...

  3. POJ 1904 King's Quest(SCC的巧妙应用,思维题!!!,经典题)

    King's Quest Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 10305   Accepted: 3798 Ca ...

  4. Poj 1904 King's Quest 强连通分量

    题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...

  5. POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)

    题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...

  6. POJ 1904 King's Quest 强连通分量+二分图增广判定

    http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #inc ...

  7. poj 1904 King's Quest tarjan求二分图的所有可选最大匹配边

    因为是完美匹配,所以每个点都已经匹配了,那么如果要选择一条别的边,增光路的最后必定找到原来所匹配的点,加上匹配的边,那么就是一个环.所以可选边在一个强连通分量里. #include <iostr ...

  8. POJ 1904 King's Quest 强联通分量+输入输出外挂

    题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配.匹配有n个数,代表某个儿子和哪个女孩可以结婚.已知这些条件,要你找出每个儿子可以和 ...

  9. [poj 1904]King's Quest[Tarjan强连通分量]

    题意:(当时没看懂...) N个王子和N个女孩, 每个王子喜欢若干女孩. 给出每个王子喜欢的女孩编号, 再给出一种王子和女孩的完美匹配. 求每个王子分别可以和那些女孩结婚可以满足最终每个王子都能找到一 ...

随机推荐

  1. CSS radial-gradient() 函数实现渐变

    值 描述 shape 确定圆的类型: ellipse (默认): 指定椭圆形的径向渐变. circle :指定圆形的径向渐变 size 定义渐变的大小,可能值: farthest-corner (默认 ...

  2. html5闰年判断函数

    <script>    var year=2016;        function runnian(year){            if (year%400==0) {return ...

  3. Python 1.安装

    Python是一种开源语言,有很多第三方库. 1. Python3 及相关组件下载及安装 a. Python3下载:https://www.python.org/downloads/->点击以下 ...

  4. 泛型List、HashTable

    从最开始接触的数组,到非泛型集合类(ArrayList.HashTable.Queue.Stack).泛型集合类(List<T>.Dictionary<T>.Queue< ...

  5. Spark学习之路 (八)SparkCore的调优之开发调优

    摘抄自:https://tech.meituan.com/spark-tuning-basic.html 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark ...

  6. C# foreach 中获取索引index的方法[转]

    在C# 开发中往往使用foreach 循环语句 来代替for循环语句.foreach 比 for 更加简洁高效.           foreach :                 foreach ...

  7. Linux环境 vi/vim ESC无法退出原因

    原因是输入模式是中文的,需要切换成英文半角符号输入命令!

  8. 创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址

    一.创建WCF服务器 1.创建WCF服务器的窗体应用程序 打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序 ...

  9. 匿名内部类和内部类中的this

    package test; public class A extends B { public String toString() { return "A"; } public s ...

  10. <转>jmeter(十三)常见问题及解决方法

    本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...