P1347 排序(拓扑排序)

Posted jindui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1347 排序(拓扑排序)相关的知识,希望对你有一定的参考价值。

这个题是我照着题解一点点理解一点点打出来的。

拓扑排序:

定义:将有向图中的顶点以线性方式进行排序。即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面。

确定一个图的拓扑排序是基于bfs的,bfs是基于队列的。

首先记录所有的点和所有点的入度(在连边时顺便求得的入度),

   if(vis[aa]!=1)	vis[aa]=1,tot++;//tot记录的是目前能算得上点(因为是随读随做)
   if(vis[cc]!=1) vis[cc]=1,tot++;
   son[aa].push_back(cc);//连边    du[cc]++;//顺便求入度

  因为每次读入数去topsort都要用到入度,所以用一个别的数组复制一遍。如果存在两个入度为0的点,则不知道该谁先谁后。则构不成拓扑序。

要是能构成的话,还需要别的边,所以是缺边,条件不足

			if(!vv)	vv=true;
			else uu=true;

  没有入度为0的点则代表有环。出现矛盾。

具体的看代码吧

技术图片
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

vector <int> son[29];
int uu,sum,duu[29],du[29],vv,p[29],vis[29],inn[29],tot,n,m,ans=-1;
queue <int> q;
char a,b,c;
bool flag;

int topsort()
    uu=false;vv=false;sum=0;
    memset(p,0,sizeof(p));
    for(int i=1;i<=26;i++)
        duu[i]=du[i];
        if(!duu[i]&&vis[i])
            if(!vv)    vv=true;
            else uu=true;
            q.push(i);
            p[++sum]=i;
        
    
    if(q.empty())    return 1;
    while(!q.empty())
        int u=q.front();vv=false;q.pop();
        for(int i=0;i<son[u].size();i++)
            duu[son[u][i]]--;
            if(duu[son[u][i]]==0)
                q.push(son[u][i]);
                if(!vv)    vv=true;
                else uu=true;
                p[++sum]=son[u][i];
            
        
    
    if(sum!=tot)    return 1;
    if(uu==true)    return 2;
    return 0;


int main()
    cin>>n>>m;
    for(int i=1;i<=m;i++)
        cin>>a>>b>>c;
        int aa=a-64,cc=c-64;
        if(vis[aa]!=1)    vis[aa]=1,tot++;
        if(vis[cc]!=1)    vis[cc]=1,tot++;
        son[aa].push_back(cc);
        du[cc]++;
        if(flag==0)    ans=topsort();
        if(ans==1&&flag==0)
            printf("Inconsistency found after %d relations.",i);
            flag=1;
        
        if(sum==n&&ans==0&&flag==0)
            printf("Sorted sequence determined after %d relations: ",i);
            for(int j=1;j<=n;j++)
                printf("%c",p[j]+64);
            printf(".");
            flag=1;
        
    
    if(flag==0)
        printf("Sorted sequence cannot be determined.");
    return 0;
View Code

 

以上是关于P1347 排序(拓扑排序)的主要内容,如果未能解决你的问题,请参考以下文章

拓扑排序

数据结构问题~啥图可以进行拓扑排序~啥图不能进行拓扑排序?

『拓扑排序』拓扑排序模板

拓扑排序算法实现

拓扑排序+关键路径

求详解 pascal 拓扑排序