Stay Hungry,Stay Foolish!

E - Find Permutation

E - Find Permutation

https://atcoder.jp/contests/abc291/tasks/abc291_e

 

思路

对于能唯一确定的情况,必然存在一个升序 路径

AX1 < AX2 < .... < AXn

*** 如果有两个及以上入度为0的起点, 则这两点的先后关系,必然无法确定,为反例

从第一个入度为0的起点开始, 使用队列依次向后遍历, 记录拓扑序, 拓扑序中元素达到n,则求出结果

如果遍历过程中队列内元素的个数大于等于2, 则表示 则等同于 *** 行的情况, 无法确定这些元素的先后关系, 为反例;

即遍历的任意时刻, 入度为0的点只可能是一个。

 

思路来自于:

https://atcoder.jp/contests/abc291/submissions/39256472

 

Code

https://atcoder.jp/contests/abc291/submissions/39292063

#include <bits/stdc++.h>
#include <vector>
using namespace std;

vector<int>ans(200005),ind(200005),v;
vector<bool>vis(200005);
map<int,vector<int> >mp;

int main(){
    int n,m;
    cin>>n>>m;
    
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        mp[a].push_back(b);
        ind[b]++;
    }
    
    queue<int>q;
    
    for(int i=1;i<=n;i++){
        if(ind[i]==0){
            vis[i]=1;
            q.push(i);
        }
    }
    
    if(q.size()!=1){
        cout<<"No"<<endl;

        return 0;
    }

    while(true){
        int num=q.front();
        q.pop();

        v.push_back(num);
        
        if (v.size() == n){
            break;
        }
        
        for(int i=0;i<mp[num].size();i++){
            int next = mp[num][i];
            ind[next]--;
            
            if((!vis[next]) && ind[next]==0){
                vis[next] = 1;
                
                q.push(next);
            }
        }
        
        if(q.size()!=1){
            cout<<"No"<<endl;
            return 0;
        }
    }
    
    cout<<"Yes"<<endl;
    
    for(int i=0;i<v.size();i++){
        ans[v[i]]=i+1;
    }
    
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<" ";
    }
    
    cout<<endl;
}

 

posted @ 2023-02-27 22:04  lightsong  阅读(37)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel