UVA1327 King's Quest

POJ1904 King's Quest


题意:

有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚。现有一个匹配表,将每个王子都与一个自己喜欢的妹子配对。请你根据这个表得出每个王子可以和几个自己喜欢的妹子结婚,按序号升序输出妹子的编号,这个表应满足所有的王子最终都有妹子和他结婚(一个妹子只能嫁给一个王子)。


看到题目时,一脸懵逼,只觉得题面很有(ci)趣(ji)

但没办法啊,为了王国的一夫一妻制我们只好努力啊awa


解析:

让我们首先来考虑建图

  • 如果王子u喜欢妹子v那我们可以从u向v连一条有向边

  • 如果妹子v可以与王子u配对(即在配对表上),那我们可以从v向u连一条有向边

对于样例

4
2 1 2
2 1 2
2 2 3
2 3 4
1 2 3 4

我们建出了这样一张图:



红的是王子,蓝的是妹子,绿的表示从王子到公主,黄的表示从妹子到王子

仔细观察我们发现了这张图的一些特别之处:

每个紫色框出的部分都是个强连通分量!

这意味着什么?

这说明这个分量内的每个王子和这个分量内的每个妹子都可以随意匹配

答案只需要枚举王子和他所在分量内的妹子即可


而这个强连通分量又该咋求呢?

当然就是tarjan啦


tips1.UVA的题目是有多组数据的,POJ的每个点只有一组数据,下面的的代码以多组数据为例,但POJ上也能过


tips2.代码中王子编号1..n,妹子编号n+1..2n


代码:

/* read() write()可以换成你自己的快读快输,因为这题数据很多 */
template<class t> void Write(t x,char c){
putchar(c);write(x);
}
const int N=2e3+5,M=2e5+N;
int en,h[N<<1],n,m,dfn[N<<1],low[N<<1],st[N<<1],num,cnt,bel[N<<1],top,ans[N];
struct edge{int n,v;}e[M]; //前向星存边
inline void add(const int &x,const int &y){e[++en]=(edge){h[x],y};h[x]=en;}
void tarjan(int x){ //tarjan求强连通分量
st[++top]=x; //手打堆
dfn[x]=low[x]=++num;
for(int i=h[x];i;i=e[i].n){
int y=e[i].v;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(!bel[y])
low[x]=min(low[x],dfn[y]);
}
if(low[x]==dfn[x]){
cnt++;
int TOP;
do{
TOP=st[top--];
bel[TOP]=cnt; //表示每个王子的所属强连通分量
}while(TOP!=x);
}
}
signed main(){
while(~scanf("%d",&n)){
en=num=cnt=top=0;
memset(h,0,sizeof h);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(bel,0,sizeof bel);
for(int i=1,k;i<=n;i++){
read(k);
for(int j=1,x;j<=k;j++){
read(x);
add(i,x+n); //从王子向妹子连边
}
}
for(int i=1,x;i<=n;i++){
read(x);
add(x+n,i); //从妹子向王子连边
}
for(int i=1;i<=n<<1;i++) if(!dfn[i])
tarjan(i); //跑tarjan
for(int u=1;u<=n;u++){ //枚举王子
int nm=0;
for(int i=h[u];i;i=e[i].n){ //枚举王子喜欢的妹子
int v=e[i].v;
if(bel[u]==bel[v]) ans[++nm]=v-n; //判断王子和妹子是否在同一强连通分量中
}
sort(ans+1,ans+1+nm); //要求按妹子编号升序输出
write(nm); //每个王子的可匹配妹子数
for(int i=1;i<=nm;i++)
Write(ans[i],' ');
puts("");
}
}
}

UVA1327 && POJ1904 King's Quest(tarjan+巧妙建图+强连通分量+缩点)的更多相关文章

  1. HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...

  2. tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)

    这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...

  3. Tarjan算法求有向图强连通分量并缩点

    // Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #inc ...

  4. 【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点

    Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...

  5. 『Tarjan算法 有向图的强连通分量』

    有向图的强连通分量 定义:在有向图\(G\)中,如果两个顶点\(v_i,v_j\)间\((v_i>v_j)\)有一条从\(v_i\)到\(v_j\)的有向路径,同时还有一条从\(v_j\)到\( ...

  6. Tarjan在图论中的应用(一)——用Tarjan来实现强连通分量缩点

    前言 \(Tarjan\)是一个著名的将强连通分量缩点的算法. 大致思路 它的大致思路就是在图上每个联通块中任意选一个点开始进行\(Tarjan\)操作(依据:强连通分量中的点可以两两到达,因此从任意 ...

  7. 【原创】tarjan算法初步(强连通子图缩点)

    [原创]tarjan算法初步(强连通子图缩点) tarjan算法的思路不是一般的绕!!(不过既然是求强连通子图这样的回路也就可以稍微原谅了..) 但是研究tarjan之前总得知道强连通分量是什么吧.. ...

  8. 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)

    题目大意:CodeVs2822的简单版本 传送门 $Tarjan$强连通分量+缩点,若连通块的个数等于一则输出n:若缩点后图中出度为0的点个数为1,输出对应连通块内的点数:否则输出0: 代码中注释部分 ...

  9. 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 ...

随机推荐

  1. VS下对Resx资源文件的操作

    原文:VS下对Resx资源文件的操作 读取 using System.IO; using System.Resources; using System.Collections; using Syste ...

  2. WPF显示html的几种方法

    原文:WPF显示html的几种方法 客户希望系统在一些特定的条件下,界面上能显示用户自定义的格式和内容,格式和内容通过html指定. 基本上在wpf中显示html有以下四种方法. 1.       W ...

  3. 微信小程序把玩(十九)radio组件

    原文:微信小程序把玩(十九)radio组件 radio组件为单选组件与radio-group组合使用,使用方式和checkbox没啥区别 主要属性: wxml <!--设置监听器,当点击radi ...

  4. KmdKit4D 0.01正式版发布了(0.02版已放出)(Delphi做驱动)

    此版本较0.01预览版已经有了脱胎换骨的变化,主要表现在以下几个方面:    1.对程序的结构进行了调整,将原来的ntutils.dcu分成fcall.dcu.halfcall.dcu和macros. ...

  5. CentOS7中firewalld的安装与使用详解

    一.软件环境 [root@Geeklp201 ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 二.安装firewall ...

  6. C#每天进步一点--异步编程模式

    C#可以有一个简单易用的机制用于异步执行方法,那就是委托.下面我介绍三种模式,对于这三种模式来说,原始线程都发起了一个异步方法,然后做一些其他处理.然而这些模式不同的是,原始线程获取发起的线程已经完成 ...

  7. 跨平台网络通信与服务器框架 acl 3.2.0 发布,acl_cpp 是基于 acl 库的 C++ 库

    acl 3.2.0 版本发布了,acl 是 one advanced C/C++ library 的简称,主要包括网络通信库以及服务器框架库等功能,支持 Linux/Windows/Solaris/F ...

  8. 从 docker 到 runC

    笔者在前文<RunC 简介>和<Containerd 简介>中分别介绍了 runC 和 containerd.本文我们将结合 docker 中的其它组件探索 docker 是如 ...

  9. JavaScript规定了几种语言类型?

    JavaScript中的每一个值都有它自己的类型,JavaScript规定了七种语言类型: 1.Undefined 2.Null 3.Boolean 4.String 5.Number 6.Symbo ...

  10. play框架之简介

    Play Framework是一个开源的Web框架,背后商业公司是Typesafe.要介绍Play之前,首先理清Play的两个不同的分支. Play 1.x 使用Java开发,最新版本是1.3.1,只 ...