题目大意

N个点的有向图中,定义“好点”为: 
从该点v出发可以到达的所有点u,均有一条路径使得u可达v。 
求出图中所有的“好点”,并按照顺序从小到大输出出来。

题目分析

图存在多个强连通分支,强连通分支内的所有点的行为可以视为一个点的行为:若强连通分支可以到达其他强连通分支,则该强连通分支内的所有点均可以到达其他分支;若强连通分支可以被其他点到达,则该强连通分支内的所有点均可以被其他点到达。因此,将图的强连通分支缩成一个点是一个经常会进行的操作。 
    将强连通分支缩成一个点之后,形成一个有向无环图。在有向无环图中,出度为0的点所代表的强连通分支,显然满足“好点”的要求;而出度不为0的点,显然存在它可以到达的点,但这些点不能到达它,故不满足“好点”的要求。因此,“好点”就是出度为0的点代表的强连通分支内的点。

实现(c++)

#include<stdio.h>
#include<string.h>
#include<vector>
#include<stack>
#include<set>
using namespace std;
#define MAX_NODE 5005
#define min(a, b) a < b? a:b
#define max(a, b) a > b? a:b vector<int> gGraph[MAX_NODE];
stack<int> gStack;
int gDfn[MAX_NODE];
int gLow[MAX_NODE]; bool gVisited[MAX_NODE];
bool gInStack[MAX_NODE];
int gClusterOfNode[MAX_NODE];
int gIndex;
int gClusterIndex; //Tarjan算法求强连通分支
void Tarjan(int u){
gDfn[u] = gLow[u] = ++gIndex;
gInStack[u] = true;
gVisited[u] = true;
gStack.push(u); for (int i = 0; i < gGraph[u].size(); i++){
int v = gGraph[u][i];
if (!gVisited[v]){
Tarjan(v);
gLow[u] = min(gLow[u], gLow[v]);
}
else if (gInStack[v]){
gLow[u] = min(gLow[u], gDfn[v]);
}
}
if (gDfn[u] == gLow[u]){
int v;
do{
v = gStack.top();
gStack.pop();
gInStack[v] = false;
gClusterOfNode[v] = gClusterIndex;
} while (v != u);
++gClusterIndex;
}
}
vector<set<int> >gLinkFrom; //每个强连通分支,入点集合
vector<set<int> > gLinkTo; //每个强连通分支,出点集合
void ReconstructGraph(int nodes, int clusters){
gLinkFrom.clear();
gLinkFrom.resize(clusters);
gLinkTo.clear();
gLinkTo.resize(clusters); for (int u = 1; u <= nodes; u++){
for (int i = 0; i < gGraph[u].size(); i++){
int v = gGraph[u][i];
int uc = gClusterOfNode[u];
int vc = gClusterOfNode[v];
if (uc != vc){ //注意!!!
gLinkTo[uc].insert(vc);
gLinkFrom[vc].insert(uc);
}
}
}
} int main(){
int n, r;
while (scanf("%d", &n) && n != 0){ scanf("%d", &r); for (int i = 0; i <= n; i++){
gGraph[i].clear();
} int u, v;
for (int i = 0; i < r; i++){
scanf("%d %d", &u, &v);
gGraph[u].push_back(v);
} memset(gVisited, false, sizeof(gVisited));
memset(gInStack, false, sizeof(gInStack));
gIndex = gClusterIndex = 0;
for (int i = 1; i <= n; i++){
if (!gVisited[i])
Tarjan(i);
} ReconstructGraph(n, gClusterIndex); //将染色后的图进行重构(即设置强连通分支) set<int> zero_outdegree_cluster_id; //出度为0的强连通分支的集合
for (int i = 0; i < gClusterIndex; i++){
if (gLinkTo[i].empty()){ //出度为0,强连通分支
zero_outdegree_cluster_id.insert(i);
}
} //遍历每个点,判断其是否属于那些出度为0的强连通分支
for (int u = 1; u <= n; u++){
if (zero_outdegree_cluster_id.find(gClusterOfNode[u]) != zero_outdegree_cluster_id.end()){
printf("%d ", u);
}
} printf("\n");
}
return 0;
}

poj_2553 强连通分支&出度为0的点的更多相关文章

  1. POJ1236 (强连通分量缩点求入度为0和出度为0的分量个数)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13804   Accepted: 55 ...

  2. POJ 1236 Network Of Schools (强连通分量缩点求出度为0的和入度为0的分量个数)

    Network of Schools A number of schools are connected to a computer network. Agreements have been dev ...

  3. poj 1236 Network of Schools(连通图入度,出度为0)

    http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  4. POJ2186 (强连通分量缩点后出度为0的分量内点个数)

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27820   Accepted: 11208 De ...

  5. POJ-2186 Popular Cows,tarjan缩点找出度为0的点。

    Popular Cows 题意:一只牛崇拜另外一只牛,这种崇拜关系可以传导.A->B,B->C =>A->C.现在给出所有的关系问你有多少牛被其他所有的牛都崇拜. 思路:就是一 ...

  6. POJ2553 强连通出度为0的应用

    题意:       给你一个有向图,然后问你有多少个满足要求的点,要求是: 这个点能走到的所有点都能走回这个点,找到所有的这样的点,然后排序输出. 思路:       可以直接一遍强连通缩点,所点之后 ...

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

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

  8. poj 2186 强连通分支 和 spfa

    思路: 建图时,分别建正向图edge和转置图T.用正向图edge来DFS,找出第一个被发现的强连通分支(如果该图存在题目要求的点,那么一定就是第一个被发现的).然后用spfa跑转置图T,判断被发现的点 ...

  9. poj 1236 Network of Schools【强连通求孤立强连通分支个数&&最少加多少条边使其成为强连通图】

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13800   Accepted: 55 ...

随机推荐

  1. linux查找系统中占用磁盘空间最大的文件

    Q:下午有一客户磁盘空间占用很大,使用df查看磁盘剩余空间很小了,客户想知道是哪些文件占满了文件. Q1:在Linux下如何查看系统占用磁盘空间最大的文件? Q2:在Linux下如何让文件夹下的文件让 ...

  2. 【Unity/Kinect】Kinect实现UI控件的点击

    用体感来实现UI控件的点击,如点击按钮. 做法:用一个图片表示左手手掌,图片位置追踪左手手掌移动,当手掌位于UI控件的矩形内时,握拳表示点击该控件. using UnityEngine; using ...

  3. 【Visual Studio】控制台程序运行时一闪而过

    问题:写一个C#控制台程序,运行时控制台一闪而过.程序结束.无法看清控制台输出的结果. 办法: 方法一二三都有人写过百度经验了:怎么解决VS运行程序一闪而过 其实还有一种办法,就是把控制台程序改为Wi ...

  4. [DNS]部署局域网DNS服务器

    This is a step by step tutorial on how to install and configure DNS server for your LAN using bind9. ...

  5. Windows 2008 R2组策略之二——GPO初探

    与前一篇博文发表已经相去月余了,实在是有些不好意思了.感谢51CTO的大编们将小文加了推荐,这使我更加觉得自己产出太少,难于回馈大家的厚爱. 今天将这个系列的第二篇奉献给大家,以伺视听. 在上篇小文中 ...

  6. 向大家推荐一个C/C++通用Makefile

    在使用 Makefile 之前,只需对它进行一些简单的设置即可:而且一经设置,即使以后对源程序文件有所增减一般也不再需要改动 Makefile.因此,即便是一个没有学习过 Makefile 书写规则的 ...

  7. esayUI实践的一些体会

    1.如何在页面中使用 easy ui ? 引入 四个文件 <!-- 引入easy ui --> <link rel="stylesheet" type=" ...

  8. 关于Javascript判断变量是否为空

    如何判断Javascript对象是否存在 原文网址:http://www.ruanyifeng.com/blog/2011/05/how_to_judge_the_existence_of_a_glo ...

  9. 关于Cocos2d-x对象的定义和创建

    游戏可以包含很多个场景,每个场景又包含很多的层,每个层又包含很多的节点,这些节点,层,场景都可以看成一个一个的对象,我们把每一个彼此不同但又是同类型的对象归为一个类,为它创建一个单独的类,这个类有这些 ...

  10. asp.net mvc webconfig配置文件操作

    读取web.config数据,可以不用编译.如发布后,非常有用web.config文件<configuration> <appSettings> <add key=&qu ...