题意:

给你n个点,和m条单向边,问你有多少点满足(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}关系,并把这些点输出(要注意的是这个关系中是蕴含关系而不是且(&&)关系)

题解:

单独一个强连通分量中的所有点是满足题目要求的
但如果它连出去到了其他点那里,要么成为新的强连通分量,要么失去原有的符合题目要求的性质
所以只需tarjan缩点求出所有强连通分量,再O(E)枚举所有边,是否会成为连接一个分量与另一个分量的边——即一条出度——即可
如果一个分量没有出度,那么他中间的所有点都是符合题目要求的点

代码(多组输入记得每次初始化):

  1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<map>
7 #include<vector>
8 #include<math.h>
9 #define mem(a,x) memset(a,x,sizeof(a))
10 using namespace std;
11 const int maxn=50005;
12 const int mod=26;
13 const int INF=0x3f3f3f3f;
14 struct edge
15 {
16 int u,v,next;
17 bool sign;
18 } e[maxn*2];
19 int head[maxn],cnt;
20 void add_edge(int x,int y)
21 {
22 e[cnt].u=x;
23 e[cnt].v=y;
24 e[cnt].next=head[x];
25 head[x]=cnt++;
26 }
27 int dfn[maxn],low[maxn],stacks[maxn],top,tot;
28 int taj;
29 int belong[maxn],visit[maxn],result[maxn];
30 vector<int>w[maxn];
31 void tarjan(int x,int fx)
32 {
33 dfn[x]=low[x]=++tot;
34 stacks[top++]=x;
35 visit[x]=1;
36 for(int i=head[x]; i!=-1; i=e[i].next)
37 {
38 int v=e[i].v;
39 if(!dfn[v])
40 {
41 tarjan(v,x);
42 low[x]=min(low[x],low[v]);
43 if(dfn[x]<low[v])
44 {
45 e[i].sign=1;
46 }
47 }
48 else if(visit[v])
49 {
50 low[x]=min(low[x],dfn[v]);
51 }
52 }
53 if(low[x]==dfn[x])
54 {
55 int now;
56 taj++;
57 w[taj].clear();
58 do
59 {
60 now=stacks[--top];
61 visit[now]=0;
62 belong[now]=taj;
63 w[taj].push_back(now);
64 }
65 while(now!=x);
66 }
67 }
68 void tarjan_init(int n)
69 {
70 memset(visit,0,sizeof(visit));
71 memset(low,0,sizeof (low));
72 memset(dfn,0,sizeof (dfn));
73 memset(stacks,0,sizeof (stacks));
74 memset(belong,0,sizeof belong);
75 top=tot=taj=0;
76 for(int i=1; i<=n; ++i)
77 {
78 if(!dfn[i]) tarjan(i,i);
79 }
80 }
81 vector<int>g[maxn];
82 int cu[maxn],ru[maxn];
83 void suodian()
84 {
85 memset(cu,0,sizeof(cu));
86 memset(ru,0,sizeof(ru));
87 for(int i=1; i<=taj; ++i)
88 g[i].clear();
89 for(int i=0; i<cnt; ++i)
90 {
91 int u=belong[e[i].u];
92 int v=belong[e[i].v];
93 if(u!=v) g[u].push_back(v),cu[u]++,ru[v]++;//printf("%d %d\n",u,v);
94 }
95 }
96 int vis[maxn];
97 void init()
98 {
99 memset(head,-1,sizeof(head));
100 cnt=0;
101 }
102 int main()
103 {
104 int n,m;
105 while(~scanf("%d",&n))
106 {
107 if(n==0) return 0;
108 scanf("%d",&m);
109 init();
110 for(int i=1; i<=m; ++i)
111 {
112 int a,b;
113 scanf("%d%d",&a,&b);
114 add_edge(a,b);
115 }
116 tarjan_init(n);
117 suodian();
118 int index=0;
119 for(int i=1;i<=n;++i)
120 {
121 if(cu[belong[i]]==0)
122 result[index++]=i;
123 }
124 if(index==0)
125 {
126 printf("\n");
127 continue;
128 }
129 sort(result,result+index);
130 for(int i=0;i<index;++i)
131 if(i==index-1)
132 printf("%d\n",result[i]);
133 else printf("%d ",result[i]);
134 }
135 return 0;
136 }

POJ - 2553 tarjan算法+缩点的更多相关文章

  1. tarjan算法+缩点--cojs 908. 校园网

    cojs 908. 校园网 ★★   输入文件:schlnet.in   输出文件:schlnet.out   简单对比时间限制:1 s   内存限制:128 MB USACO/schlnet(译 b ...

  2. POJ 1470 Tarjan算法

    裸的LCA,读入小坑.Tarjan算法大坑,一开始不知道哪儿错了,后来才发现,是vis数组忘了清零了(⊙﹏⊙)b 傻傻的用了邻接矩阵...很慢啊,1100多ms. Closest Common Anc ...

  3. tarjan算法+缩点:求强连通分量 POJ 2186

    强连通分量:1309. [HAOI2006]受欢迎的牛 ★★   输入文件:cow.in   输出文件:cow.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 每一头牛 ...

  4. POJ 1236 Network of Schools (tarjan算法+缩点)

    思路:使用tarjan求强连通分量并进行缩点,判断所有入度为0的点,这个点就是必须要给予文件的点,分别计算出度,入度为零的点的个数,取二者的最大值就是把这个图变成强连通需要加的边数. 一个取值需要讨论 ...

  5. POJ 2553 Tarjan

    题意:如果v点能到的所有点反过来又能到v点,则v点是sink点,排序后输出所有的sink点. 思路:Tarjan缩点,输出所有出度为0的连通块内的点. PS:一定要记得把数组清零!!!!!!!否则自己 ...

  6. poj 2553 强连通分支与缩点

    思路:将所有强连通分支找出来,并进行缩点,然后找其中所有出度为0的连通分支,就是题目要求的. #include<iostream> #include<cstdio> #incl ...

  7. POJ 1236 Tarjan算法

    这道题认真想了想.. [ 题目大意:有N个学校,从每个学校都能从一个单向网络到另外一个学校,两个问题 1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 2:至少需要添加几条 ...

  8. tarjan算法(求强连通子块,缩点)

    tarjan算法求图中的强连通子图的个数. #include<iostream> #include<stack> #include<queue> #include& ...

  9. poj2186tarjan算法缩点求出度

    poj2186tarjan算法缩点求出度 自己打一遍第一题,入门啦,入门啦 题目还算简单,多头牛,给你仰慕关系(可传递),问你最后有没有牛被所有的牛仰慕 根据关系可以建图,利用tarjan算法缩点处理 ...

随机推荐

  1. Azure Table Storage(一) : 简单介绍

    Azure Table Storage是什么: Azure Table Storage是隶属于微软Azure Storage这个大服务下的一个子服务, 这个服务在Azure上算是老字号了, 个人大概在 ...

  2. 【Spring】Spring中的Bean - 2、Baen的实例化 (构造器、静态工厂、实例工厂)

    Bean的实例化 文章目录 Bean的实例化 构造器实例化 静态工厂方式实例化 实例工厂方式实例化 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-S ...

  3. 【System】paging和swaping之间的区别是什么?

    分析paging和swapping的区别,首先要了解内存管理 当虚拟内存用二级存储(物理磁盘)作为主存的扩展时,内核会尽力保持最活跃的数据在主存中.有一下两个内核例程做这件事情: 1.交换(swapp ...

  4. mysql锁表问题

    查看当前所有的进程信息: show full processlist; 查看当前所有的事务 select * from information_schema.innodb_trx; 查看当前出现的锁 ...

  5. C++:I/O流的概念和流类库的结构

    一.C++输入输出包含以下三个方面的内容: 对系统指定的标准设备的输入和输出.即从键盘输入数据,输出到显示器屏幕.这种输入输出称为标准的输入输出,简称标准I/O. 以外存磁盘文件为对象进行输入和输出, ...

  6. Docker相关简介以及使用方法

    Docker: 可以把它看作是一个软件,在这个软件当中呢,还可以安装其他的软件,还可以把软件所需要的环境依赖一起添加进来,这样让开发人员的程序在不同的环境当中都可以流转起来,避免了程序出现" ...

  7. .net code+vue 文件上传

    后端技术 .net code 官方文档 https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/file-uploads?view=aspnet ...

  8. 2020 CSP&NOIP 游记

    CSP初赛 CSP初赛 Day -1 早上打了模拟赛,T2寒假正好做过,然而还是还是被踩Orz,郑外NB!.中午出校吃了大盘鸡和拉面,还带回来了三瓶可乐. 初赛知识点看了两页不(看)想(不)看(懂)了 ...

  9. java虚拟机入门(五)- 常见垃圾回收器及jvm实现

    上节讲完了垃圾回收的基础,包括java的垃圾是什么,如何寻找以及常用的垃圾回收算法,那么那么多的理论知识讲完了,具体是什么样的东西在做着回收垃圾的事情呢?我们接下来就好好聊聊jvm中常用的垃圾回收器. ...

  10. Promise用法

    1.概述 Promise是一步编程的一种解决方案,从语法上讲,promise是一个对象,从它可以获取异步的问题 Promise的优点: 可以避免多次异步调用嵌套导致的回调地域 提供了简洁的api,使得 ...