1385E. Directing Edges(拓撲序的應用)

游辰發表於2024-05-01

背景:本題為構造DAG題,給出了有向與無向邊,CF2000分題目

   思路:先處理有向圖,判斷是否有環,有就NO,否則一定有解.

   我們思考一下有環的條件(或者說環在什麼情況下產生):即後面的數指向前面的數才可能構成環,即拓撲序大的指回去了!

   故得構造思路:即讓無向邊的拓撲序小的指向大的即不會產生環

   細節:想想全為無向邊的情況下處理

程式碼如下:

點選檢視程式碼
//背景:本題為構造DAG題,給出了有向與無向邊,CF2000分題目
/*思路:先處理有向圖,判斷是否有環,有就NO,否則一定有解.
       我們思考一下有環的條件(或者說環在什麼情況下產生):即後面的數指向前面的數才可能構成環,即拓撲序大的指回去了!
       故得構造思路:即讓無向邊的拓撲序小的指向大的即不會產生環*/
//細節:想想全為無向邊的情況下處理
#include <bits/stdc++.h>
using namespace std;
void Solve()
{
    int n,m,t,x,y;
    cin>>n>>m;
    vector<int> e1[n+1];//鄰接表存有向圖
    vector<pair<int,int>>e2;//存無向邊
    int topos[n+1];//記錄拓撲序
    int in[n+1];//記錄入度
    memset(topos,0,sizeof(topos));//初始拓撲序為0
    memset(in,0,sizeof(in));//初始化入度為0
    for (int i = 1;i<=m;i++)//輸入邊
    {
        cin>>t>>x>>y;
        if(t == 0)
        {
            e2.push_back({x,y});//無向
        }
        else
        {
            in[y]++;
            e1[x].push_back(y);//有向
        }
    }
    queue<int> que;//拓撲佇列
    for (int i = 1;i<=n;i++)//這裡跟以前的不太一樣!!!採用了遍歷而非拓撲圖中存在的點,即也處理不在拓撲圖中的點,其入度必為0
    {
        if(in[i] == 0) que.push(i);
    }
    int ans = 0;//初始化計數
    while(!que.empty())//拓撲排序(顯然優先處理入度為0的,所以不在拓撲圖中的點也會被計算且被賦予拓撲序,神來之筆),而不在拓撲圖中的點的拓撲序必然小!!
    {
        x = que.front();
        que.pop();
        ans++;
        topos[x] = ans;//記錄當前點的拓撲序
        for (auto v:e1[x])
        {
            in[v]--;
            if(in[v] == 0) que.push(v);
        }
    }
    if(ans < n)//以n為判斷環的標準了!!!
    {
        cout<<"NO"<<"\n";
        return;
    }
    cout<<"YES"<<"\n";
    for (int i = 1;i<=n;i++)//先輸出有向邊
    {
        for (auto v:e1[i]) cout<<i<<" "<<v<<"\n";
    }
    for (auto v:e2)//處理無向邊,由小向大輸出
    {
        if(topos[v.first] < topos[v.second]) cout<<v.first<<" "<<v.second<<"\n";
        else cout<<v.second<<" "<<v.first<<"\n";
    }
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        Solve();
    }
    return 0;
}


/*我的Hack資料:
  1
  4 4
  0 1 2
  0 2 3
  0 3 4
  0 4 1
*/
多多支援!!!

相關文章