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
原创粉丝点击