codevs 2822 爱在心中(Tarjan 缩点)
来源:互联网 发布:摩托车 知乎 编辑:程序博客网 时间:2024/05/19 13:07
go to problem
题目描述 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 71 22 33 24 24 55 66 4
样例输入2:
3 31 22 12 3
样例输出 Sample Output
样例输出1:
22 3
样例输出2:
1-1
很明显,爱心天使就是环,第一问就是找环的个数。
至于第二问,tarjan后统计每个环的出度。如果一个爱心天使要被其他所有人或爱心天使所爱,那他一定是没有出度的。反之,若这个环有出度,同时又可以被所有点到达,那便会形成一个更大的环,与Tarjan的结果相矛盾。所以我们的答案就是没有出度的环。注意要处理自环的情况。
特别的:
1.如果有一个点(自环)没有出度,则输出-1;
2.如果有多个环都没有出度,则输出-1;
代码。。。
写的略丑(*/ω\*)
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<vector>#include<algorithm>using namespace std;int N,M,Scc_cnt,cnt,top,f,F,Ans;int First[100010],Next[100010]; int Dfn[100010],Low[100010],Stack[100010],ans[50010];int Scc_belong[100010],Scc_out[50010];bool Instack[100010];vector<int> Scc[50050];struct maple{ int f,t;}Love[100010];void Tarjan(int n){ Dfn[n]=Low[n]=++cnt; Stack[++top]=n; Instack[n]=1; for(int i=First[n];i;i=Next[i]) { if(!Dfn[Love[i].t]) { Tarjan(Love[i].t); Low[n]=min(Low[n],Low[Love[i].t]); } else if(Instack[Love[i].t]) Low[n]=min(Low[n],Dfn[Love[i].t]); } if(Low[n]==Dfn[n]) { ++Scc_cnt; int k; do{ k=Stack[top--]; Instack[k]=0; if(Scc_belong[k]!=Scc_cnt) //? Scc[Scc_cnt].push_back(k); Scc_belong[k]=Scc_cnt; }while(k!=n); }}int main(){ scanf("%d%d",&N,&M); for(int i=1;i<=M;++i) { scanf("%d%d",&Love[i].f,&Love[i].t); Next[i]=First[Love[i].f]; First[Love[i].f]=i; } for(int i=1;i<=N;++i) if(!Dfn[i]) Tarjan(i); for(int i=1;i<=N;++i) for(int j=First[i];j;j=Next[j]) if(Scc_belong[i]!=Scc_belong[Love[j].t]) ++Scc_out[Scc_belong[i]]; for(int i=1;i<=Scc_cnt;++i) { if(Scc[i].size()!=1) ++Ans; if(Scc_out[i]==0&&Scc[i].size()!=1) { ++f,cnt=Scc[i].size(); for(int j=0;j<cnt;++j) ans[j]=Scc[i][j]; sort(ans,ans+cnt); } if(Scc_out[i]==0&&Scc[i].size()==1) F=1; } cout<<Ans<<'\n'; if(!f||F||f>1) cout<<-1; else for(int i=0;i<cnt;++i) cout<<ans[i]<<" "; return 0;}
阅读全文
0 0
- codevs 2822 爱在心中(Tarjan 缩点)
- <tarjan算法练习-缩点>codevs 2822 爱在心中
- codevs 2822 爱在心中(Tarjan)
- [codevs 2822] 爱在心中 【tarjan 算法】
- 爱在心中【tarjan + 缩点】
- Codevs 2822 爱在心中 [强连通分量] [Tarjan]
- codevs 2822 爱在心中 Tarjan 解题报告
- Codevs 2822 爱在心中
- codevs 2822 爱在心中
- Codevs 2822 爱在心中
- 【codevs 2822】爱在心中
- 【codevs 2822】爱在心中
- Codevs 2822 爱在心中
- 爱在心中 CODEVS
- codevs爱在心中(强联通分量,缩点,求出度为0的点)缩点模版
- codevs 2822 爱在心中(强连通分量)
- tarjan题目(2)爱在心中
- 【codevs2822】 爱在心中 tarjan+统计点的个数
- Spring Boot shiro 权限管理 小例子
- JDBC的使用(一)
- SSH框架模板
- GITC 2017全球互联网技术大会.北京站 早鸟票抢购啦!
- BootStrap模态框,点击保存后实现模态框自动关闭的思路
- codevs 2822 爱在心中(Tarjan 缩点)
- Effective Java(鼓励使用泛型、消除非受检警告)
- 08.多表查询下篇
- 如何发表期刊流程
- 对angular4的认识
- 类型分类
- C#学习笔记12-GC的工作原理基础和垃圾回收机制
- 【原+转】用CMake代替makefile进行跨平台交叉编译
- (数据库)-存储过程