zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    C++实现反射
    ubuntu下安装secureCRT(含破解方法)
    2018 年力扣高频算法面试题汇总-难题记录-鸡蛋掉落
    对于opencv全面貌的认识和理解
    关于c++类的一些知识的总结
    vs2017+opencv4.0.1安装配置详解(win10)
    leetcode-120-三角形最小路径和
    leetcode-64-最小路径和
    leetcode-917-仅仅反转字母
    leetcode-914-卡牌分组
  • 原文地址:https://www.cnblogs.com/cloudplankroader/p/13341693.html
Copyright © 2011-2022 走看看