您的位置:首页 > 其它

图结构练习——判断给定图是否存在合法拓扑序列

2015-08-11 08:37 288 查看
一、概述

 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。

 通常,这样的线性序列称为满足拓扑次序(TopoiSicai Order)的序列,简称拓扑序列。

二、无前趋的顶点优先的拓扑排序方法  

  该方法的每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为:

   NonPreFirstTopSort(G){//优先输出无前趋的顶点

     while(G中有人度为0的顶点)do{

      从G中选择一个人度为0的顶点v且输出之;

        从G中删去v及其所有出边;

     }

     if(输出的顶点数目<|V(G)|)

     //若此条件不成立,则表示所有顶点均已输出,排序成功。

      Error("G中存在有向环,排序失败!");

     }

<pre name="code" class="cpp">    int graph[narray][narray]; //邻接阵
    int indegree[narray]; //记录顶点的入度
    int n; //n为顶点个数
    memset(graph,0,sizeof(graph));
    memset(indegree,0,sizeof(indegree));
    for(i=1;i<=n;++i) //遍历n次每次找出一个顶点
    {
        for(j=1;j<=n;++j) //遍历所有的结点
        {
            if(indegree[j]==0)
            {
                indegree[j]--; //该顶点的入度为-1,防止该顶点被在此遍历到
                if(i!=n) printf("%d ",j);
                else printf("%d\n",j);
                for(k=1;k<=n;++k)
                {
                     if(graph[j][k])
                         indegree[k]--; //与该顶点关联的顶点的入度递减
                }
                break;
            }
        }
    }  




三、无后继的顶点优先的拓扑排序方法

1、思想方法

 该方法的每一步均是输出当前无后继(即出度为0)的顶点。对于一个DAG,按此方法输出的序列是逆拓扑次序。因此设置一个栈(或向量)T来保存输出的顶点序列,即可得到拓扑序列。若T是栈,则每当输出顶点时,只需做人栈操作,排序完成时将栈中顶点依次出栈即可得拓扑序列。若T是向量,则将输出的顶点从T[n-1]开始依次从后往前存放,即可保证T中存储的顶点是拓扑序列。

2、抽象算法描述 

 算法的抽象描述为: 

 NonSuccFirstTopSort(G){//优先输出无后继的顶点 

  while(G中有出度为0的顶点)do { 

  从G中选一出度为0的顶点v且输出v; 

  从G中删去v及v的所有人边   } 

  if(输出的顶点数目<|V(G)|)  

Error("G中存在有向环,排序失败!");   }

图结构练习——判断给定图是否存在合法拓扑序列Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^题目描述给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。输入输入包含多组,每组格式如下。

第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)后面m行每行两个整数a b,表示从a到b有一条有向边。输出若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。示例输入1 02 21 22 1示例输出YESNO

1、无前趋的顶点优先的拓扑排序

#include<bits/stdc++.h>
using namespace std;
int ma[20][20],vis[20],out[20];
int n,m;
void creat()    //构建图
{
    int a,b,i;
    memset(ma,0,sizeof(ma));
    memset(vis,0,sizeof(vis));
    memset(out,0,sizeof(out));
    for(i=1; i<=m; i++)
    {
        cin>>a>>b;
        if(ma[a][b]==0)
        {
            ma[a][b]=1;
            out[b]++;      //存入每个节点的入度,入度++
        }
    }
}
void qsort()
{
    int i,f,k,j;
    for(i=1; i<=n; i++)
    {
        f=0;
        for(j=1; j<=n; j++)
        {
            if(vis[j]==0&&out[j]==0)    //若该点未被访问过,且入度为0
            {
                vis[j]=1;   //标记该点已被访问过
                for(k=1; k<=n; k++)
                {
                    if(ma[j][k]==1)    //找到入度为一的点
                    {
                        out[k]--;    //将入度减1,保证可以得到下一个输出点
                    }
                }
                f=1;
                break;
            }
        }
        if(f==0)
            break;
    }
    if(f==1)
    {
        printf("YES\n");
    }
    else printf("NO\n");
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        creat();
        qsort();
    }
    return 0;
}


2、无后缀的顶点优先拓扑排序

#include<bits/stdc++.h>
using namespace std;
int ma[20][20],vis[20],out[20];
int n,m;
void creat()    //构建图
{
    int a,b,i;
    memset(ma,0,sizeof(ma));
    memset(vis,0,sizeof(vis));
    memset(out,0,sizeof(out));
    for(i=1; i<=m; i++)
    {
        cin>>a>>b;
        if(ma[a][b]==0)
        {
            ma[a][b]=1;
            out[a]++;      //存入每个节点的出度,出度++
        }
    }
}
void qsort()
{
    int i,f,k,j;
    for(i=1; i<=n; i++)
    {
        f=0;
        for(j=1; j<=n; j++)
        {
            if(vis[j]==0&&out[j]==0)    //若该点未被访问过,且出度为0
            {
                vis[j]=1;   //标记该点已被访问过
                for(k=1; k<=n; k++)
                {
                    if(ma[k][j]==1)    //找到出度为一的点
                    {
                        out[k]--;    //将出度减1,保证可以得到下一个输出点
                    }
                }
                f=1;
                break;
            }
        }
        if(f==0)
            break;
    }
    if(f==1)
    {
        printf("YES\n");
    }
    else printf("NO\n");
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        creat();
        qsort();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: