Tarjan

2822 爱在心中

** 时间限制: 1 s

** 空间限制: 128000 KB

** 题目等级 : 钻石 Diamond

题解

题目描述 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

codevs2282

1,求大小大于1的强联通个数,强联通缩点后,如果出度为0的强联通个数只有一个,输出这个强联通的元素,否则输出-1

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue> using namespace std;
const int maxn = 1e5+7;
const int maxm = maxn << 2; int n,m; struct Node {
int to,w,next;
} edge[maxm];
int first[maxn],sign; int dfn[maxn],low[maxn],vis[maxn],inx,cnt,col[maxn],num[maxn]; int outdegree[maxn]; stack<int>s; void clear_arr() {
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
memset(col,0,sizeof(col));
memset(num,0,sizeof(num));
memset(outdegree,0,sizeof(outdegree));
inx = cnt = 1;
while(s.size()) {
s.pop();
}
} void init() {
for(int i = 1; i <= n; i ++ ) {
first[i] = 0;
}
sign = 1;
} void add_edge(int u,int v,int w) {
edge[sign].to = v;
edge[sign].w = w;
edge[sign].next = first[u];
first[u] = sign ++;
} void tarjan(int x) {
dfn[x] = low[x] = inx ++;
s.push(x);
vis[x] = 1; for(int i = first[x]; i ; i = edge[i].next ) {
int to = edge[i].to;
if(!dfn[to]) {
tarjan(to);
low[x] = min(low[x],low[to]);
}
else if(vis[to]) {
low[x] = min(low[x],dfn[to]);
}
}
int now;
if(low[x] == dfn[x]) {
do {
now = s.top();
s.pop();
vis[now] = 0;
col[now] = cnt;
num[cnt] ++;
} while(now != x);
cnt ++;
} } int main()
{
int u,v,w;
while(~scanf("%d %d",&n,&m)) {
init();
vector<pair<int,int> >vec;
for(int i = 1; i <= m; i ++ ) {
scanf("%d %d",&u,&v);
add_edge(u,v,1);
vec.push_back(make_pair(u,v));
}
clear_arr();
for(int i = 1; i <= n; i ++ ) {
if(!dfn[i]) {
tarjan(i);
}
} int god = 0;
for(int i = 1; i < cnt; i ++ ) {
if(num[i] > 1) {
god ++;
}
}
printf("%d\n",god); for(int i = 0; i < vec.size(); i ++ ) {
u = vec[i].first;
v = vec[i].second;
if(col[u] != col[v]) {
outdegree[col[u]] ++;
}
} int pos = -1, number = 0;
for(int i = 1; i < cnt ; i ++ ) {
if(outdegree[i] == 0 && num[i] > 1) {
pos = i;
number ++;
}
}
if(number == 1) {
vector<int>ans;
for(int i = 1; i <= n; i ++ ) {
if(col[i] == pos) {
ans.push_back(i);
}
}
for(int i = 0; i < ans.size(); i ++ ) {
if(i == 0) {
printf("%d",ans[i]);
} else {
printf(" %d",ans[i]);
}
}
puts("");
} else {
puts("-1");
}
} return 0;
}

最新文章

  1. cant create oci environment
  2. zendFream 中的用到了Ajax(其中有搜索)分页
  3. 用JS制作简易的可切换的年历,类似于选项卡
  4. (六) 6.2 Neurons Networks Backpropagation Algorithm
  5. vim常用命令 vim键盘布局
  6. BZOJ 4311 向量
  7. JS七种加密解密方法
  8. Unity3D GUI学习之GUILayout控件及使用
  9. iPhone、iPad默认按钮样式问题
  10. base64这种编码的意义
  11. poj_3461: Oulipo
  12. c#代码技巧
  13. Java集合源码分析(四)HashMap
  14. Java_修饰符
  15. bootstrap-datetimepicker的中文显示问题
  16. Java线程的5种状态及切换(透彻讲解)-京东面试
  17. 顶部BANNER
  18. Linux free -m 详解命令
  19. OPENSSL问题,使用fsockopen()函数提示错误
  20. 剑指offer--49.矩阵中的路径

热门文章

  1. Python入门之函数的嵌套/名称空间/作用域/函数对象/闭包函数
  2. 使用SQL语句在SQL server2017上创建数据库
  3. Canvas-自由绘制
  4. jacascript 原生选项卡插件
  5. MyBatis(1)——快速入门
  6. rocketmq番外篇(一):开发命令行
  7. java中String类学习笔记
  8. ubuntu14.4 分辨率偏低
  9. [LeetCode] Squirrel Simulation 松鼠模拟
  10. [LeetCode] Brick Wall 砖头墙壁