codevs 2822 爱在心中(Tarjan)
来源:互联网 发布:lol韩服网络错误 编辑:程序博客网 时间:2024/05/19 12:26
题目描述 Description
“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。”
在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。
如果有这样一部分人,他们彼此都相爱,则他们就超越了一切的限制,用集体的爱化身成为一个爱心天使。
现在,我们想知道在这个爱的国度里会出现多少爱心天使。而且,如果某个爱心天使被其他所有人或爱心天使所爱则请输出这个爱心天使是由哪些人构成的,否则输出-1。输入描述 Input Description
第1行,两个数N、M,代表爱的国度里有N个人,爱的关系有M条。
第2到第M+1行,每行两个数A、B,代表A爱B。输出描述 Output Description
第1行,一个数,代表爱的国度里有多少爱心天使。
第2行,如果某个爱心天使被其他所有人和爱心天使所爱则请输出这个爱心天使是由哪些人构成的(从小到大排序),否则输出-1。样例输入 Sample Input
样例输入1:
6 7
1 2
2 3
3 2
4 2
4 5
5 6
6 4样例输入2:
3 3
1 2
2 1
2 3样例输出 Sample Output
样例输出1:
2
2 3样例输出2:
1
-1数据范围及提示 Data Size & Hint
各个测试点1s
题解:这道题的第一问是求强连通分量的数量,第二问是求强连通分量缩点后出度为零的点,如果出度为零的点不止一个,输出 -1。所以我们只要用Tarjan求一下强连通分量就行了。
PS:这题连数据范围都没有,差评╭(╯^╰)╮
代码如下:
#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int MAXV=10100;const int MAXE=10100;int first[MAXV],nxt[MAXE<<1];int dfn[MAXV],low[MAXV];//dfn记录按顺序遍历时点的编号//low记录当前点能找到的最早的与他在一个强连通分量的点的编号 int stack[MAXV],scc[MAXV],size[MAXV],du[MAXV];int n,m,tot,tot1,snum,cnt;bool in_stack[MAXV];struct edge{ int from,to;}es[MAXE<<1];void init(){ memset(first,-1,sizeof(first)); tot=0;}void build(int f,int t){ es[++tot]=(edge){f,t}; nxt[tot]=first[f]; first[f]=tot;}void group(int u)//Tarjan求强连通分量 { dfn[u]=low[u]=++tot1; stack[++snum]=u; in_stack[u]=1; for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(!dfn[v]) { group(v);//遍历每一个点 low[u]=min(low[u],low[v]);//更新搜到点的low值 } else if(in_stack[v]) low[u]=min(low[u],dfn[v]);//找到一个强连通分量 } if(dfn[u]==low[u])//找到这个强连通分量的起点序号 { cnt++; while(stack[snum+1]!=u)//把栈中元素依次弹出直到弹出点u,这些点组成一个强连通分量 { scc[stack[snum]]=cnt; in_stack[stack[snum]]=0; size[cnt]++;//记录强连通分量的大小 snum--; } }}int main(){ scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); build(u,v); } for(int i=1;i<=n;i++) if(!dfn[i]) group(i);//找图中的强连通分量 for(int i=1;i<=n;i++) for(int j=first[i];j!=-1;j=nxt[j]) { int v=es[j].to; if(scc[i]!=scc[v]) du[scc[i]]++;//记录缩点后的强连通分量的出度 } int sum1=0,sum2=0,x; for(int i=1;i<=cnt;i++) { if(size[i]>1) sum1++; if(!du[i]) { sum2++; x=i; } } printf("%d\n",sum1); if(sum2==1&&size[x]!=1) { for(int i=1;i<=n;i++) if(scc[i]==x) printf("%d ",i);//输出强连通分量中的点 } else printf("-1"); return 0;}
- codevs 2822 爱在心中(Tarjan)
- [codevs 2822] 爱在心中 【tarjan 算法】
- codevs 2822 爱在心中(Tarjan 缩点)
- Codevs 2822 爱在心中 [强连通分量] [Tarjan]
- <tarjan算法练习-缩点>codevs 2822 爱在心中
- codevs 2822 爱在心中 Tarjan 解题报告
- Codevs 2822 爱在心中
- codevs 2822 爱在心中
- Codevs 2822 爱在心中
- 【codevs 2822】爱在心中
- 【codevs 2822】爱在心中
- Codevs 2822 爱在心中
- 爱在心中 CODEVS
- codevs 2822 爱在心中(强连通分量)
- tarjan题目(2)爱在心中
- codevs2822 爱在心中(tarjan求缩点的度)
- 爱在心中【tarjan + 缩点】
- VIJOS-P1626 爱在心中 tarjan
- Android 打开各种文件的方法
- 数据表与简单Java类映射-依靠代码链
- vb 引用adodb问题
- 简易的顺序栈
- PHP学习(1)--数据库的连接
- codevs 2822 爱在心中(Tarjan)
- 如何保证Service不被杀死一直运行
- The resource could not be loaded because the App Transport Security policy requires the use of a sec
- 机器学习基石(林轩田)——笔记1
- 大话-从市场需求->芯片设计->SDK开发->Turnkey方案->定制化产品 --- SDK开发(三) 即将开启大话专题 ISP篇,希望喜欢大话技术的读者加群147565042,我们一起“吹”集结号
- 灰常简易的顺序队列
- 小波的秘密10_图像处理应用:图像增强
- MongoDB 那些坑
- [hard]273. Integer to English Words