zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    HDU 5640 King's Cake
    HDU 5615 Jam's math problem
    HDU 5610 Baby Ming and Weight lifting
    WHU1604 Play Apple 简单博弈
    HDU 1551 Cable master 二分
    CodeForces659C Tanya and Toys map
    Codeforces 960E 树dp
    gym 101485E 二分匹配
    Codeforces 961E 树状数组,思维
    Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板
  • 原文地址:https://www.cnblogs.com/jindui/p/11203386.html
Copyright © 2011-2022 走看看