codeforces-1385E(拓撲排序)

Directing Edges

題目描述:

給定n個點m條邊,其中一些邊是有向的,一些邊是無向的,現在你需要將這些無向的邊確定方向,並判斷是否可以生成一個有向無環圖

思路:

顯而易見如果給出的有向邊沒有形成環的話,剩下的無向邊一定可以使他們不形成環,於是只需要將給定的有向邊做一遍拓撲排序,判斷是否已經成環,未成環的話就將所有無向邊按拓撲序定向即可使圖無環

代碼:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e6;
const double PI = acos(-1.0);
#define Test ll tesnum;tesnum = read();while(tesnum--)
ll read();
vector<int> g[200005];
vector<pair<int,int>> v;
int deg[N],pos[N];
int cnt;
int main()
{
    Test{
        cnt = 0;
        v.clear();
        int n,m;
        cin>>n>>m;
        for(int i = 1; i <= n; i++)g[i].clear();
        for(int i = 1; i <= n; i++)deg[i] = pos[i] = 0;
        for(int i = 1; i <= m; i++){
            int w,x,y;
            cin>>w>>x>>y;
            v.emplace_back(make_pair(x,y));
            if(w==1){
                g[x].emplace_back(y);
                deg[y]++;
            }
        }
        queue<int> q;
        for(int i = 1; i <= n; i++){
            if(deg[i]==0)
                q.push(i);
        }
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            pos[u] = ++cnt;
            for(int i = 0; i < g[u].size(); i++){
                deg[g[u][i]]--;
                if(deg[g[u][i]]==0){
                    q.push(g[u][i]);
                }
            }
        }
        if(cnt==n){
            cout<<"YES"<<endl;
            for(auto x:v){
                if(pos[x.first]>pos[x.second]){
                    cout<<x.second<<" "<<x.first<<endl;
                }else
                    cout<<x.first<<" "<<x.second<<endl;
            }
        }else{
            cout<<"NO"<<endl;
        }

    };
    return "BT7274", NULL;
}

inline ll read() {
    ll hcy = 0, dia = 1;char boluo = getchar();
    while (!isdigit(boluo)) {if (boluo == '-')dia = -1;boluo = getchar();}
    while (isdigit(boluo)) {hcy = hcy * 10 + boluo - '0';boluo = getchar();}
    return hcy * dia;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章