POJ 1904:King's Quest【tarjan】
题目大意:给出一个二分图的完美匹配(王子和公主的烧死名单表),二分图x部和y部均只有n个点,问对于每一个x部的点,他能选择哪些点与之匹配 使得与之匹配后,剩余图的最大匹配仍然是n
思路:这题是大白书379页二分图的压轴题,在图论刷的题还不多时思考过这题,现在想来也不难想
这题引人瞩目的一点便是预先给出了一个二分图的初始匹配
对每个点枚举后增广显然不怎么可行,那么还是图论问题的经典思考方式,点和边各表示什么
题目的输入天然的给出了一个图,但对这题好像没什么用处,于是开始思考把给出的初始匹配的每条边看成一个点!!!
那样构成的图每个点就是一个王子和一个公主的配对,如果一个王子还可以花心爱上除了初始匹配的公主外的其他公主,那么从这个点向那个公主处连一条边
然后显然新构成的图中如果有环,(A到B,B又可以到A),那么我们就可以把原来二分图中的匹配顺次沿一格(形象一点就是环中的王子们顺次把自己初始匹配的姑娘送给下一个王子),这样肯定不改变二分图的最大匹配数
然后联想到在一个强连通分量里面,任意两点间肯定是有环的,因此可以缩点,一个SCC里的姑娘肯定可以取到的,不在一个SCC里的姑娘由于是DAG 所以不可能存在环,因此无论如何也取不到
然后就A了,输出的时候得递增 因此贡献了发WA
#include<cstdio>
#include<string.h>
#include<iostream>
#include<algorithm>
#define maxn 600090
using namespace std;
int head[maxn],next[maxn],point[maxn],now=0;
int stack[maxn],top,col,dfn[maxn],low[maxn];
int tim,belong[maxn],x[maxn],y[maxn];
int match[maxn],ans[maxn],h=0,idx=0;
bool instack[maxn];
void add(int x,int y)
{
next[++now]=head[x];
head[x]=now;
point[now]=y;
}
void tarjan(int k)
{
stack[++top]=k;
dfn[k]=low[k]=++tim;
instack[k]=1;
for(int i=head[k];i;i=next[i])
{
int u=point[i];
if(dfn[u]==0)
{
tarjan(u);
low[k]=min(low[k],low[u]);
}
else if(instack[u]==1)
{
low[k]=min(low[k],low[u]);
}
}
if(dfn[k]==low[k])
{
col++;
int u;
do
{
u=stack[top--];
belong[u]=col;
instack[u]=0;
}while(u!=k);
}
}
int main()
{
int n,k,tt;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&k);
for(int j=1;j<=k;j++)
{
scanf("%d",&tt);
x[++h]=i;y[h]=tt;
}
}
for(int i=1;i<=n;i++)
{
scanf("%d",&tt);
match[tt]=i;
}
for(int i=1;i<=h;i++)
{
if(match[y[i]]!=x[i])
{
add(x[i],match[y[i]]);
}
}
for(int i=1;i<=n;i++)if(dfn[i]==0)tarjan(i);
for(int i=1;i<=n;i++)
{
int hh=0;
while(x[idx+1]==i && idx+1<=h)
{
idx++;
if(belong[i]==belong[match[y[idx]]])
ans[++hh]=y[idx];
}
printf("%d",hh);
sort(ans+1,ans+1+hh);
for(int i=1;i<=hh;i++)
{
printf(" %d",ans[i]);
}
printf("\n");
}
return 0;
}
POJ 1904:King's Quest【tarjan】的更多相关文章
- LeetCode:组合总数III【216】
LeetCode:组合总数III[216] 题目描述 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说明: 所有数字都是正整数. ...
- LeetCode:路径总和II【113】
LeetCode:路径总和II[113] 题目描述 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径. 说明: 叶子节点是指没有子节点的节点. 示例:给定如下二叉树, ...
- LeetCode:括号的分数【856】
LeetCode:括号的分数[856] 题目描述 给定一个平衡括号字符串 S,按下述规则计算该字符串的分数: () 得 1 分. AB 得 A + B 分,其中 A 和 B 是平衡括号字符串. (A) ...
- LeetCode:组合总数II【40】
LeetCode:组合总数II[40] 题目描述 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candi ...
- LeetCode:整数转罗马数字【12】
LeetCode:整数转罗马数字[12] 题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 10 ...
- LeetCode:矩阵置零【73】
LeetCode:矩阵置零[73] 题目描述 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0.请使用原地算法. 示例 1: 输入: [ [1,1,1], ...
- LeetCode:下一个排列【31】
LeetCode:下一个排列[31] 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排 ...
- LeetCode:杨辉三角【118】
LeetCode:杨辉三角[118] 题目描述 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行. 在杨辉三角中,每个数是它左上方和右上方的数的和. 示例: 输入: 5 输出: ...
- LeetCode:罗马数字转整数【13】
LeetCode:罗马数字转整数[13] 题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 10 ...
随机推荐
- AJPFX总结java 中类的创建和使用
//面向对象中类的创建和 调用 ============================================================= 类的使用: 类的使用分为两个动作:创建对象与 ...
- ES-自然语言处理
前言 自然语言处理(Natural Language Processing)是计算科学领域与人工智能领域中的一个重要方向.它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法.自然语言处理 ...
- vue中的事件监听之——v-on vs .$on
跟着视频中老师的教学视频学vue的时候,看很多时候都用@(v-on)来监听子级emit的自定义事件,但在bus总线那块,又用.$on来监听bus自身emit的事件,v-on之间似乎相似但又不同,今天对 ...
- 类似QQ在线离线好友界面
把头像设置成圆形的代码如下: package com.example.lesson6_11_id19; import android.content.Context; import android.c ...
- 用python+pygame写贪吃蛇小游戏
因为python语法简单好上手,前两天在想能不能用python写个小游戏出来,就上网搜了一下发现了pygame这个写2D游戏的库.了解了两天再参考了一些资料就开始写贪吃蛇这个小游戏. 毕竟最开始的练手 ...
- this.treeData = JSON.parse(JSON.stringify(this.d)) 树的序列化反序列化
this.treeData = JSON.parse(JSON.stringify(this.d))
- 初识WEBGL
WEBGL (全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一 ...
- CAD交互绘制带颜色宽度的直线(网页版)
用户可以在CAD控件视区任意位置绘制直线. 主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下: 参数 说明 DOUBLE dX1 直线的开始点x坐标 DOUBLE ...
- 【搜索】P1041 传染病控制
题目链接:P1041 传染病控制 题解: 这个题目是看别人的博客做出来的,其实挺不错的一个题目,考察的东西挺多的, 一个dfs可以处理5个东西: 1.找出父亲 2.找出深度 3.每一层的节点,存进Ve ...
- 使用html2canvas实现网页截图,并嵌入到PDF
使用html2canvas实现网页截图并嵌入到PDF 以前我们只能通过截图工具进行截取图像.这使得在业务生产中,变得越来越不方便.目前的浏览器功能越来越强大,H5也逐渐普及,浏览器也可以实现截图了.这 ...