UVA1327 && POJ1904 King's Quest(tarjan+巧妙建图+强连通分量+缩点)
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+巧妙建图+强连通分量+缩点)的更多相关文章
- HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...
- tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)
这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...
- Tarjan算法求有向图强连通分量并缩点
// Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #inc ...
- 【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点
Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...
- 『Tarjan算法 有向图的强连通分量』
有向图的强连通分量 定义:在有向图\(G\)中,如果两个顶点\(v_i,v_j\)间\((v_i>v_j)\)有一条从\(v_i\)到\(v_j\)的有向路径,同时还有一条从\(v_j\)到\( ...
- Tarjan在图论中的应用(一)——用Tarjan来实现强连通分量缩点
前言 \(Tarjan\)是一个著名的将强连通分量缩点的算法. 大致思路 它的大致思路就是在图上每个联通块中任意选一个点开始进行\(Tarjan\)操作(依据:强连通分量中的点可以两两到达,因此从任意 ...
- 【原创】tarjan算法初步(强连通子图缩点)
[原创]tarjan算法初步(强连通子图缩点) tarjan算法的思路不是一般的绕!!(不过既然是求强连通子图这样的回路也就可以稍微原谅了..) 但是研究tarjan之前总得知道强连通分量是什么吧.. ...
- 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)
题目大意:CodeVs2822的简单版本 传送门 $Tarjan$强连通分量+缩点,若连通块的个数等于一则输出n:若缩点后图中出度为0的点个数为1,输出对应连通块内的点数:否则输出0: 代码中注释部分 ...
- 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 ...
随机推荐
- vs2017 cordova调试android app
方案是:virtualbox + androidx86 7.0+_x64.iso虚拟机方式
- BooleanToColorConverter
public class BooleanToColorConverter : IValueConverter { public object Convert(object value, Type ta ...
- 16.09 working note
这个月最主要任务是linux shell script学习. 其次是继续spring源码学习. 其余时间C.C++和Java学习. 01 9月第一天,9点多才到家.做道简单的oj题练习下.因为简单,所 ...
- 详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)
使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...
- <%@ Application Codebehind="Global.asax.cs" Inherits="XXX.MvcApplication" Language="C#" %>
<%@ Application Codebehind="Global.asax.cs" Inherits="XXX.MvcApplication" Lan ...
- jsp中的指令与动作
JSP中的三种命令指令分别是page.include.taglib JSP中的动作元素包括:include.forward.useBean.getProperty.setProperty.plugin ...
- XMLHttpRequest对象的属性与方法
XMLHttpRequest对象是Ajax的核心,它有很多属性和方法.1,readyState属性当一个XMLHttpRequest对象被创立后,readyState属性标示了当前对象处于什么状态,可 ...
- is和==的区别以及编码和解码
一.is和==的区别 python中对象包含的三个基本要素分别是:id(身份标识),type(数据类型),value(值) is和==都是对对象进行比较判断的,但对对象比较判断的内容不同. ★==是p ...
- Spring Boot:快速入门教程
什么是Spring Boot? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人 ...
- 点菜网---Java开源生鲜电商平台-技术选型(源码可下载)
点菜网---Java开源生鲜电商平台-技术选型(源码可下载) 1.内容简介 点菜网目前选用的是最流行的微服务架构模式,采用前后端分离的开发模式,具备高可用,高负载,支持千万级别的数据量的请求. 2. ...