博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj_2553 强连通分支&出度为0的点
阅读量:6657 次
发布时间:2019-06-25

本文共 2546 字,大约阅读时间需要 8 分钟。

题目大意

    N个点的有向图中,定义“好点”为: 

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

题目分析

    图存在多个强连通分支,强连通分支内的所有点的行为可以视为一个点的行为:若强连通分支可以到达其他强连通分支,则该强连通分支内的所有点均可以到达其他分支;若强连通分支可以被其他点到达,则该强连通分支内的所有点均可以被其他点到达。因此,将图的强连通分支缩成一个点是一个经常会进行的操作 

    将强连通分支缩成一个点之后,形成一个有向无环图。在有向无环图中,出度为0的点所代表的强连通分支,显然满足“好点”的要求;而出度不为0的点,显然存在它可以到达的点,但这些点不能到达它,故不满足“好点”的要求。因此,“好点”就是出度为0的点代表的强连通分支内的点。

实现(c++)

#include
#include
#include
#include
#include
using namespace std;#define MAX_NODE 5005#define min(a, b) a < b? a:b#define max(a, b) a > b? a:bvector
gGraph[MAX_NODE];stack
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
>gLinkFrom; //每个强连通分支,入点集合 vector
> 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
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;}

 

转载地址:http://bbxto.baihongyu.com/

你可能感兴趣的文章
傲天AC EAG误配置导致Portal推送失败案例
查看>>
自制简易linux系统
查看>>
我的友情链接
查看>>
诺基亚5130XM手机上网设置
查看>>
Mybatis-Plus 之BaseMapper 方法详解
查看>>
学H3C的认证要注意的几个事情
查看>>
【sql】连续出现至少3次的数 Consecutive Numbers
查看>>
交替取值判断第一个人能否赢过第二个人 Predict the Winner
查看>>
我的友情链接
查看>>
nginx安装lua/replace-filter-nginx-module
查看>>
图像模式识别 (二)
查看>>
iptables发布nfs服务器的配置及NFS简易配置
查看>>
NDK r7 的新特性
查看>>
安装SQLSERVER2008R2保持和SQL2000独立运行的安装过程
查看>>
Heartbeat+DRBD+mysql高可用方案
查看>>
smartbits的国产版本minismb-使用burst模式
查看>>
Datastore content not visible for multiple Hosts
查看>>
【深入浅出MyBatis系列七】分页插件
查看>>
成为JavaGC专家(2)—如何监控Java垃圾回收机制
查看>>
360软件的×××查杀、漏洞修复等组件不能使用,提示runtime error
查看>>