1008. Airline Routes (35)
来源:互联网 发布:wish数据分析平台 编辑:程序博客网 时间:2024/04/30 02:23
PAT上的一道题,题目意思是给定一个有向图,判断给定两个顶点间是否有回路。若两个顶点在同一个强连通图上,那么他们之间肯定是有回路的。之前没有遇到过计算强连通图分支的问题。计算一个有向图的强连通图分支的方法是进行两次深度优先遍历。第一次在原图上进行深度优先遍历。第二次在原图的反向图上进行深度优先遍历。
深度优先遍历的方法:
一个顶点有相关的3个变量f(访问该顶点结束时间:即从该节点向下访问结束时的时间),和一个祖先顶点变量r(若从v到u有一条边,当访问到v时,再访问u时,r(u)=v)和颜色标记c,若顶点v已经被访问c,c(v) = 2(黑色),若顶点v正在访问,c(v)=1(灰色),若顶点v未被访问到c(v)=0(白色)。遍历的过程如下:
没次从顶点集中寻找一个白色v顶点,以该顶点作为深度优先搜索树根节点开始,进行一次深度优先搜索。之后从v开始,递归如下过程:v颜色设为1,访问时间+1,对v的邻接表的每一个白色节点u,r(u)=v,然后从u继续访问。当从某节点i退出访问时c(i)设为2,f(i)设置为当前访问时间。
第一访问得到的点按照访问结束时间降序排序,以此为顺序在原图的反向图上再进行一次深度优先遍历。得到各个点的祖先顶点集合r集。在r集上做并查集即可得到各个强连通图。
代码如下:
#include<vector>#include<queue>#include<algorithm>#include<stdio.h>using namespace std;struct Vertex{ int id,color,finish,root; bool operator < (Vertex const & a)const{ return finish>a.finish; }};void DFS(vector<vector<int>>& AdjCity,vector<Vertex>&vers,vector<int>&visitSort);void DFSVisit(int st,vector<vector<int>>&AdjCity,vector<Vertex> &vers,int &time){ vers[st].color = 1; ++time; for(int i=0;i<AdjCity[st].size();++i) { if(vers[AdjCity[st][i]].color==0) { vers[AdjCity[st][i]].root=st; DFSVisit(AdjCity[st][i],AdjCity,vers,time); } } vers[st].color = 2; vers[st].finish=++time;}void DFS(vector<vector<int>>& AdjCity,vector<Vertex>&vers,vector<int>&visitSort){ int time = 0; for(int i=0;i<visitSort.size();++i) { if(vers[visitSort[i]].color==0) DFSVisit(vers[visitSort[i]].id,AdjCity,vers,time); }}int findroot(vector<Vertex>&vers,int x){ if(vers[x].root==-1) return x; int r = findroot(vers,vers[x].root); vers[x].root=r; return r;}void func(vector<Vertex> &vers,vector<int> &visitSort){ vector<Vertex> vtmp=vers; sort(vtmp.begin()+1,vtmp.end()); for(int i=1;i<vers.size();++i) { visitSort[i-1]=vtmp[i].id; vers[i].color=vers[i].finish = 0; vers[i].root = -1; }}int main(){ int n,m; scanf("%d%d",&n,&m); vector<vector<int>> AdjCity0(n+1); vector<vector<int>> AdjCity1(n+1); vector<Vertex> vers(n+1); for(int i=0;i<=n;++i) { vers[i].id=i; vers[i].color=0; vers[i].finish=0; vers[i].root = -1; } for(int i=0;i<m;++i) { int st,en; scanf("%d%d",&st,&en); AdjCity0[st].push_back(en); AdjCity1[en].push_back(st); } vector<int> visitSort(n); for(int i=0;i<n;++i) { visitSort[i]=i+1; } DFS(AdjCity0,vers,visitSort); func(vers,visitSort); DFS(AdjCity1,vers,visitSort); int k; scanf("%d",&k); vector<bool> ans; for(int i=0;i<k;++i) { int st,en; scanf("%d%d",&st,&en); int r1 = findroot(vers,st); int r2 = findroot(vers,en); ans.push_back(r1==r2); } for(int i=0;i<ans.size();++i) { if(ans[i]==true) printf("Yes\n"); else printf("No\n"); } return 0;}
0 0
- 1008. Airline Routes (35)
- 1008. Airline Routes (35)解题报告
- pat-top 1008. Airline Routes (35)
- PAT (Top Level) Practise 1008Airline Routes (35)
- PAT (Top Level) Practise 1008 Airline Routes (35) (tarjan算法求强联通分量)【四星级】
- Routes
- Airline数据模型
- 自定义airline
- BOJ1018 -- Airline Hub
- UVa 10316 - Airline Hub
- URAL 1040: Airline Company
- 10316 - Airline Hub
- VIM AIRLINE 配置问题
- Shipping Routes
- Shipping Routes
- rails routes
- SERVICE ROUTES
- Routes 起步
- crazyflie-firmware之姿态解算和PID控制
- hdu 1394 Minimum Inversion Number(线段树)
- 重启博客
- 思维实验:相对论演绎思考(1)
- 将CentOS设置root自动登录
- 1008. Airline Routes (35)
- c的经典算法
- 自己动手实现Java注解(Java Annotation in Action)
- 2015-12-21,我在csdn的第一篇博客
- 235. Lowest Common Ancestor of a Binary Search Tree
- HashSet和TreeSet 分别实现对象的排序操作
- 【Unity】Log文件
- 10030---CSS 属性选择器
- 选择排序