zoukankan      html  css  js  c++  java
  • CF1385E【Directing Edges】 (拓扑排序)

    CF2000分图论

    题意:给你一个n个顶点m条边的图,其中一些边没有方向,其余边有方向,让你对每一条没有方向的边赋一个方向,要求最终图不能形成自环。(没有重边)

    题解:首先先看有方向的边所构成的图原本是否已经成环,如果成环的话必定直接输出NO,不成环的话则必定输出YES。统计每个点的indeg,进行拓扑排序,按照拓扑序的dfn顺序,把无向边的u和v两个点连线方向从拓扑序小的指向拓扑序大的。这样必定不会成环(这是拓扑排序的性质之一)

    AC代码:

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int tot,head[maxn];
    struct E{
        int to,next;
    }edge[maxn<<1];
    void add(int u,int v){
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    int n,m,indeg[maxn],dfn[maxn];
    bool topsort(){
        queue<int> q;int ct=0;
        rep(i,1,n) if(!indeg[i]) q.push(i);
        while(!q.empty()){
            int now=q.front();q.pop();
            dfn[now]=++ct;
            for(int i=head[now];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(--indeg[v]==0) q.push(v);
            }
        }
        if(ct!=n) return false;
        else return true;
    }
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            mem(indeg,0),mem(head,-1),tot=0;
            vector<pair<int,int> >vec;
            vector<pair<int,int> >lol;
            rep(i,1,m){
                int op,u,v;scanf("%d%d%d",&op,&u,&v);
                if(!op){
                    vec.pb({u,v});
                }else{
                    add(u,v);indeg[v]++;
                    lol.pb({u,v});
                }
            }
            if(!topsort()){puts("NO");continue;}
            else{
                puts("YES");
                for(auto it:vec){
                    int a=it.first,b=it.second;
                    if(dfn[a]>dfn[b]) swap(a,b);
                    printf("%d %d
    ",a,b);
                }
            }
            for(auto it:lol){
                printf("%d %d
    ",it.first,it.second);
            }
        }
    }
    View Code
    Codeforces ID:Anonytt QQ: 847399102 可以添加&关注
  • 相关阅读:
    微信小程序 功能函数 把数字1,2,3,4换成春,夏,秋,冬
    微信小程序组件 滚动导航
    微信小程序 功能函数 openid本地和网络请求
    微信小程序组件 自定义弹出框
    Log4j
    UTF-8 setup for workspace
    outlook preview setup
    eclipse 背景颜色
    sqldeveloper 英文设置
    shell spool
  • 原文地址:https://www.cnblogs.com/Anonytt/p/13621310.html
Copyright © 2011-2022 走看看