1. 程式人生 > 實用技巧 >Codeforces Round #656 (Div. 3)E. Directing Edges(拓撲排序+構造dag圖)

Codeforces Round #656 (Div. 3)E. Directing Edges(拓撲排序+構造dag圖)

題目大意

給你\(n\)個定點\(m\)條邊,這\(m\)條邊中有有向邊也有無向邊。

\(t=0\)時,輸入邊代表的是無向邊。

\(t=1\)時,輸入的邊代表的是\(x->y\)的有向邊。

要你將所有的無向邊變為有向邊後整個圖是無環的(有向無環圖)。

思路

有向邊時建邊而且更新入度,無向邊時只存邊不更新入度。

然後在拓撲排序時將無向邊插進去,由於在插無向邊的時候沒有影響到拓撲排序的順序,所以插入後並不會影響原來拓撲排序的有無環性。

為什麼拓撲排序時插入無向邊不影響整個拓撲排序?

因為當我們插入時,沒有影響到其他任何邊入度變化,也不會因為插入導致後面拓撲排序的順序改變。

本題根據有向完成拓撲排序後,只需要將無向再處理一下。按拓撲排序的順序從小到大即可(因為這樣就不會影響拓撲排序的順序,從而說明仍然可以按照原來的拓撲排序去走。因為你把邊放在了從前到後,回憶拓撲排序過程,增加這條邊不會影響之前所有點的入度,因此拓撲排序不變。而當這個點被去除後,新增加的邊也被刪除了,因此也不影響後面)

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<"  : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;
//#define int long long
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 2e5 + 10;

int n,m;
vector<int>e1[maxn],e2[maxn];
int deg[maxn];
vector<pii >ans;
int vis[maxn];

void topo(){
    queue<int>q;
    while(!q.empty())q.pop();
    for(int i=1;i<=n;++i){
        if(deg[i]==0){
            q.push(i);
        }
    }
    int cnt=0;
    while(!q.empty()){
        int now=q.front();q.pop();
        vis[now]=1;
        ++cnt;
        for(auto v:e1[now]){
            --deg[v];
            if(deg[v]==0&&vis[v]==0){
                q.push(v);
            }
            ans.push_back({now,v});
        }
        for(auto v:e2[now]){
            if(vis[v]==0){
                ans.push_back({now,v});
            }
        }

    }
    if(cnt==n){
        cout<<"YES\n";
        for(auto i:ans){
            cout<<i.first<<" "<<i.second<<endl;
        }
    }else{
        cout<<"NO\n";
    }

}

void solve(){
    cin>>n>>m;
    ans.clear();
    for(int i=0;i<=n;++i){
        deg[i]=0;
        e1[i].clear();e2[i].clear();
        vis[i]=0;
    }
    int t,x,y;
    for(int i=1;i<=m;++i){
        cin>>t>>x>>y;
        if(t==0){
            e2[x].push_back(y);
            e2[y].push_back(x);
        }else{
            e1[x].push_back(y);
            ++deg[y];
        }
    }
    topo();

}


int main(){
    int __;
    cin>>__;
//    scanf("%d",&__);
    while(__--){
        solve();
    }

}

E. Directing Edges
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a graph consisting of n vertices and m edges. It is not guaranteed that the given graph is connected. Some edges are already directed and you can't change their direction. Other edges are undirected and you have to choose some direction for all these edges.

You have to direct undirected edges in such a way that the resulting graph is directed and acyclic (i.e. the graph with all edges directed and having no directed cycles). Note that you have to direct all undirected edges.

You have to answer t independent test cases.

Input
The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.

The first line of the test case contains two integers n and m (2≤n≤2⋅105, 1≤m≤min(2⋅105,n(n−1)2)) — the number of vertices and the number of edges in the graph, respectively.

The next m lines describe edges of the graph. The i-th edge is described with three integers ti, xi and yi (ti∈[0;1], 1≤xi,yi≤n) — the type of the edge (ti=0 if the edge is undirected and ti=1 if the edge is directed) and vertices this edge connects (the undirected edge connects vertices xi and yi and directed edge is going from the vertex xi to the vertex yi). It is guaranteed that the graph do not contain self-loops (i.e. edges from the vertex to itself) and multiple edges (i.e. for each pair (xi,yi) there are no other pairs (xi,yi) or (yi,xi)).

It is guaranteed that both sum n and sum m do not exceed 2⋅105 (∑n≤2⋅105; ∑m≤2⋅105).

Output
For each test case print the answer — "NO" if it is impossible to direct undirected edges in such a way that the resulting graph is directed and acyclic, otherwise print "YES" on the first line and m lines describing edges of the resulted directed acyclic graph (in any order). Note that you cannot change the direction of the already directed edges. If there are several answers, you can print any.

參考部落格:https://blog.csdn.net/Satur9/article/details/107436886
https://blog.csdn.net/woshixuxiran/article/details/107428917