E. Directing Edges——(拓扑排序)

题意

根据图给的边,构造一个有向无环图(标准的拓扑排序)。

总结

比赛中,自己在考虑出度,不知道自己在什么。
出度为0干嘛:我挺服自己的
入度为0:代表这个点不在有向无环图,然后不断的拆边,入度减减,构造,存在环的话,肯定边数构造会少。
用set存在好处
1:可以删边
2:知道u,可以判断是否存在u-v这条边。(本题作用:判断有向边 or 无向边)

题目链接

//#pragma GCC optimize(2)
//#pragma GCC target ("sse4")
#include
//typedef long long ll;
#define ull       unsigned long long
#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<
#define eps         1e-6
#define base        131
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define ferma(a,b)  pow(a,b-2)
#define mod(x)      (x%mod+mod)%mod
#define pb          push_back
#define decimal(x)  cout << fixed << setprecision(x);
#define all(x)      x.begin(),x.end()
#define rall(x)      x.rbegin(),x.rend()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
template<typename T> inline T fetch(){T ret;cin >> ret;return ret;}
template<typename T> inline vector<T> fetch_vec(int sz){vector<T> ret(sz);for(auto& it: ret)cin >> it;return ret;}
template<typename T> inline void makeUnique(vector<T>& v){sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());}
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
    //  freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int N = 2e5 + 5;
vector<set<int> > G(N);
int in[N];
signed main()
{
    IOS;
    file();
    int t;
    cin>>t;
    while(t--)
    {
        int n, m;
        cin>>n>>m;
        for(int i = 1; i <= n; i++)
            G[i].clear(),in[i] = 0;
        set<int>se;
        while(m--)
        {
            int tag,x,y;
            cin>>tag>>x>>y;
            se.insert(x);
            se.insert(y);
            G[x].insert(y);
            if(tag)
                in[y]++;
            else
                G[y].insert(x);
        }
        queue<int>que;
        for(int i=1;i<=n;i++)
            if(in[i]==0)
                que.push(i),se.erase(i);
        vector<pair<int,int> > ans;
        while(!que.empty())
        {
            int u = que.front();
            que.pop();
            vector<int>vec;
            for(auto v:G[u])
            {
                if(!G[v].count(u))
                    in[v]--;
                if(!in[v]&&se.count(v))
                    que.push(v),se.erase(v);
                ans.pb({u,v});
                vec.pb(v);
            }
            for(auto v:vec)
                G[u].erase(v),G[v].erase(u);
        }
        if(se.empty())
        {
            cout<<"YES"<<endl;
            for(auto it:ans)
                cout<<it.F<<" "<<it.S<<endl;
        }
        else
            cout<<"NO"<<endl;
    }



    return 0;
}

你可能感兴趣的:(#,拓扑)