拓扑排序

含义

  • 对于一个有向无环图,将所有节点做成线性序列,并要求每条边的起点在终点前面。如果存在这种序列,那就是满足拓扑序列,过程称为拓扑排序

常见所需元素

  • 图向量(同最短路径)
  • 入度数组
  • 队列(如果需要输出,要用到优先队列)

模板(自创)

vector<int> graph[500];		//图
int indegree[500];			//入度数组

bool TopologicalSort(int n){
    queue<int> node;
    for(int i=0;i<n;i++){		//首先筛选入度为0的点
        if(indegree[i]==0){
            node.push(i);
        }
    }
    int number=0;
    while(!node.empty()){
        int u=node.front();
        node.pop();
        number++;
        for(int i=0;i<graph[u].size();i++){		//更新入度,并且再次判断
            int v=graph[u][i];
            indegree[v]--;
            if(indegree[v]==0){
                node.push(v);
            }
        }
    }
    return n==number;
} 

int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        if(n==0 && m==0){
            break;
        }
        memset(graph,0,sizeof(graph));
        memset(indegree,0,sizeof(indegree));
        while(m--){
            int from,to;
            cin>>from>>to;
            graph[from].push_back(to);
            indegree[to]++;
        }
        if(TopologicalSort(n)){
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

变形

变形可能为输出排序结果(一般会有多种,按序号顺序输出)

vector<int> graph[501];
int indegree[501];

vector<int> topo(int n){
    priority_queue<int,vector<int>,greater<int> > Q;		//优先队列用于按序号顺序输出
    vector<int> ans;			//输出向量
    for(int i=1;i<=n;i++){
        if(indegree[i]==0){
            Q.push(i);
        }
    }
    while(!Q.empty()){
        int u=Q.top();
        Q.pop();
        ans.push_back(u);		//多一步加入到向量
        for(int i=0;i<graph[u].size();i++){
            int v = graph[u][i];
            indegree[v]--;
            if(indegree[v]==0){
                Q.push(v);
            } 
        }
    }
    return ans;
}

int main(){
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF){
        memset(graph,0,sizeof(graph));
        memset(indegree,0,sizeof(indegree));
        while(m--){
            int from,to;
            cin>>from>>to;
            graph[from].push_back(to);
            indegree[to]++;
        }
        vector<int> ans;
        ans = topo(n);
        for(int i=0;i<ans.size();i++){
            if(i==0)
                cout<<ans[i];
            else
                cout<<" "<<ans[i];
        }
        cout<<endl;
    }
    return 0;
} 

例题

posted @ 2021-03-25 13:25  LazyXx  阅读(37)  评论(0编辑  收藏  举报