poj 1904(强连通分量+输入输出外挂)
题目链接:http://poj.org/problem?id=1904
题意:有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王子可以和几个妹子结婚,按序号升序输出妹子的编号,这个表应满足所有的王子最终都有妹子和他结婚。
分析:很好的图论题,把强连通分量和完美匹配结合起来了,记得多校的时候看到类似的题目(hdu 4685),但是不会做,还以为是二分匹配=_=
首先建图,如果王子u喜欢妹子v,则建一条边u指向v(u,v),对于大臣给出的初始完美匹配,如果王子u和妹子v结婚,则建一条边v指向u(v,u),然后求强连通分量,
对于每个王子和妹子,如果他们都在同一个强连通分量内,则他们可以结婚。
为什么呢?因为每个王子只能和喜欢的妹子结婚,初始完美匹配中的丈夫和妻子之间有两条方向不同的边可以互达,则同一个强连通分量中的王子数和妹子数一定是相等的,若王子x可以和另外的一个妹子a结婚,妹子a的原配王子y肯定能找到另外一个妹子b结婚,因为如果找不到的话,则x和a必不在同一个强连通分量中。
所以一个王子可以和所有与他同一强连通分量的妹子结婚,而这不会导致同一强连通分量中的其他王子找不到妹子结婚。
好像很绕的样子@_@。。。。。大家在纸上画画图吧
建图的时候王子从1~n编号,妹子从n+1~2*n编号
这一题的数据量挺大的,光是输入输出就会消耗很多时间了,可以用输入输出外挂来加速读入和输出。
不加输入外挂9000+ms
加输入外挂8000+ms
加输入输出外挂500+ms
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N=+;
const int M=+;
struct EDGE{
int v,next;
}edge[M];
int first[N],low[N],dfn[N],sta[M],belong[N],ans[N];
bool instack[N];
int g,cnt,top,scc; void AddEdge(int u,int v)
{
edge[g].v=v;
edge[g].next=first[u];
first[u]=g++;
}
int min(int a,int b)
{
return a<b?a:b;
}
void Tarjan(int u) //求强连通分量
{
int i,v;
low[u]=dfn[u]=++cnt;
sta[++top]=u;
instack[u]=true;
for(i=first[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
scc++;
while()
{
v=sta[top--];
instack[v]=false;
belong[v]=scc; //缩点
if(u==v)
break;
}
}
}
int Scan() //输入外挂
{
int res=,ch,flag=;
if((ch=getchar())=='-')
flag=;
else if(ch>=''&&ch<='')
res=ch-'';
while((ch=getchar())>=''&&ch<='')
res=res*+ch-'';
return flag?-res:res;
}
void Out(int a) //输出外挂
{
if(a>)
Out(a/);
putchar(a%+'');
}
int main()
{
int n,i,u,v,k;
while(scanf("%d",&n)!=EOF)
{
g=cnt=top=scc=;
memset(first,-,sizeof(first));
memset(dfn,,sizeof(dfn));
memset(instack,false,sizeof(instack));
for(i=;i<=n;i++)
{
// scanf("%d",&k);
k=Scan();
while(k--)
{
// scanf("%d",&v);
v=Scan();
AddEdge(i,v+n); //王子i喜欢妹子v
}
}
for(i=;i<=n;i++)
{
// scanf("%d",&v);
v=Scan();
AddEdge(v+n,i); //王子i可以和妹子v结婚
} for(i=;i<=*n;i++) //求强连通分量
if(!dfn[i])
Tarjan(i); for(u=;u<=n;u++)
{
int count=;
for(i=first[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(belong[u]==belong[v]) //同一个强连通分量
ans[count++]=v-n;
}
sort(ans,ans+count);
// printf("%d",count);
Out(count);
for(i=;i<count;i++)
{
//printf(" %d",ans[i]);
putchar(' ');
Out(ans[i]);
}
// printf("\n");
putchar('\n');
}
}
return ;
}
poj 1904(强连通分量+输入输出外挂)的更多相关文章
- poj 1904(强连通分量+完美匹配)
传送门:Problem 1904 https://www.cnblogs.com/violet-acmer/p/9739990.html 参考资料: [1]:http://www.cnblogs.co ...
- poj 1904 强连通分量
思路:先有每个儿子向所有他喜欢的姑娘建边,对于最后给出的正确匹配,我们建由姑娘到相应王子的边.和某个王子在同一强连通分量,且王子喜欢的姑娘都是该王子能娶得.思想类似匈牙利算法求匹配的时候,总能找到增广 ...
- poj 2186 强连通分量
poj 2186 强连通分量 传送门 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 33414 Acc ...
- POJ 1904 King's Quest 强联通分量+输入输出外挂
题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配.匹配有n个数,代表某个儿子和哪个女孩可以结婚.已知这些条件,要你找出每个儿子可以和 ...
- poj 2762(强连通分量+拓扑排序)
题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...
- poj 1236(强连通分量分解模板题)
传送门 题意: N(2<N<100)个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输. 问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都 ...
- POJ(2186)强连通分量分解
#include<cstdio> #include<vector> #include<cstring> using namespace std; ; vector& ...
- Popular Cows POJ - 2186(强连通分量)
Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10, ...
- Poj 1904 King's Quest 强连通分量
题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...
随机推荐
- leetcode 206. Reverse Linked List(剑指offer16)、
206. Reverse Linked List 之前在牛客上的写法: 错误代码: class Solution { public: ListNode* ReverseList(ListNode* p ...
- 18核心的Intel i9将在2019年夏发布
受工艺和架构限制,Intel HEDT发烧级桌面平台面对AMD早已经优势不再,但升级仍然在继续. 去年10月份,Intel一方面发布了第二代酷睿i9 X系列,仍然基于14nm Skylake-X架构, ...
- linux安装sonar
第一步 使用上一篇博客中下载的sonar6.7.6上传到centos7 准备 安装jdk1.8 解压unzip sonarqube-6.7.6.zip 由于elasticsearch需要非root用户 ...
- highcharts中把X轴的名字竖着显示
Highcharts.chart('container', { chart: { type: 'column' }, title: { text: 'Auto rotation limit' }, s ...
- eaeyui-combobox实现组合查询(即实现多个值得搜索)
2015年9月1日,今天要实现下拉框的组合查询功能,即可以再下拉框中选择多个值,输入框中每个值之间有逗号隔开,传到后台,由split函数将其分割开,组合成数组,在由sql查询. 实现的效果是: 当时在 ...
- ShellExecute使用详解
ShellExecute命令 ⑴ 函数原型: HINSTANCE ShellExecute(HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTST ...
- Python基础语法复习
1.数据类型 List 列表 函数 append(): 在列表末尾追加. count(): 计算对象在列表中出现的次数. extend():将列表内容添加到列表中. index(): 计算对象在列表中 ...
- Solr数据库导入
Solr数据库导入 1.在MySQL中创建一张表t_solr,并插入测试数据. 2.把E:\Solr\solr-4.10.4\example\example-DIH\solr\db\conf下的adm ...
- Node.js系列-express(下)
前言 距上次更新博客又两个月多了,这两个月内除了上班时间忙公司的项目外,下班后也没有闲着,做了点外包,有小程序的,管理端的项目.也可能那段时间做的外包项目也都比较急,所以晚上都搞到一点左右睡,严重的压 ...
- vsftpd虚拟账户配置
1. 概述 FTP是文件传输协议,在内外网的文件传输中使用广泛. 本篇博客主要介绍FTP服务器的部署和测试. 2. 软件环境部署 查看系统是否安装FTP软件(vsftpd),执行命令:rpm -qa ...