• 排序(拓扑好题)


    ------------恢复内容开始------------

    题面:https://www.luogu.com.cn/problem/P1347


    明确题目中三种结果的关系。

    对于每一个输入的条件,我们都进行拓扑。

    Ⅰ如果发现本次拓扑进入队列的点不是所有的点 ,说明有环,那么后续无论如何都是不能确定大小关系的,直接输出

    Ⅱ如果单次有两个入度为0的点压入队列,那我们是不能确定大小关系的

    Ⅳ不满足以上条件且所有的点都进入了队列,那说明可行

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,vis[39],indug[39],t[39];
    string a[30009];
    vector<int>vec[39];
    string s;
    int tuopu(int k)
    {
        queue<int>q;
        int up=0,f=0,num=0;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]&&!t[i])//字母出现过
            {
                f++;num++;s+=char(i+'A'-1);
                q.push(i);
                if(f>1)    up=1;//无法判断    
            } 
        }
        while(!q.empty())
        {
            int now=q.front();q.pop();
            int f=0;//同理,如过一次出现2个点,无法判断 
            for(int i=0;i<vec[now].size();i++)
            {
                int w=vec[now][i];
                if(--t[w]==0)
                {
                    f++;
                    if(f>1)        up=1;//无法判断关系 
                    s+=char(w+'A'-1);
                    num++;
                    q.push(w);
                }
            }
        }
        if(num!=k)    return -1;//出现环
        if(up)    return 100;//无法判断 
        if(num==n)    return 1;//成功 
    }
    int main()
    {
            cin>>n>>m;
            for(int i=0;i<=26;i++)    vec[i].clear();
            memset(vis,0,sizeof(vis));
            memset(indug,0,sizeof(indug));
            for(int i=1;i<=m;i++)    cin>>a[i];
            int i,k=0,ok=-1;//出现的字母数 
            string ans;s="";
            for(i=1;i<=m;i++)
            {
                s="";//每次tuopu构造的字符串 
                int l=a[i][0]-'A'+1,r=a[i][2]-'A'+1;
                vec[l].push_back(r);indug[r]++;
                for(int j=0;j<=26;j++)    t[j]=indug[j];//供tuopu使用 
                if(vis[l]==0)    k++;
                if(vis[r]==0)    k++;//统计目前有多少字符 
                vis[l]=vis[r]=1;
                int z=tuopu(k); 
                if(z==-1)    break;//有环 
                if(z==1)//成功 
                {
                    ans=s,ok=i;
                    break;
                }
            }
            if(i!=m+1&&ok==-1)//有环形,矛盾
                cout<<"Inconsistency found after "<<i<<" relations."<<endl; 
            else if(ok!=-1)//成功 
                cout<<"Sorted sequence determined after "<<ok<<" relations: "<<ans<<"."<<endl;
            else
                cout<<"Sorted sequence cannot be determined."<<endl;    
    }

     

    ------------恢复内容结束------------

  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12503302.html
Copyright © 2020-2023  润新知