E. Directing Edges

题意:给出n个点和m条边

  m条边有两种类型

  一种是已经确定了方向的边,一种是还未确定方向的边

  要求让我们确定所有边的方向后,图无环

思路:我们先按已经确定方向的边建图跑拓扑排序

   然后再按跑拓扑排序的顶点的顺序来建未确定方向的边即可

   那么怎么确立呢?即:顶点在拓扑排序中小的建向大的,这样建肯定能满足无环

   为什么呢?因为我们在把这些不确定方向的边加进去的时候

   如果是从小的往大的加,那么在重新跑拓扑排序的时候,小的肯定是先跑到的,然后他就能消除了这一条边的入度

   然后大的边到最后也能跑到

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
using namespace std;
const int maxn=2e5+10;
struct node
{
    int op,u,v;
}a[maxn];
struct hah
{
    int v,nxt;
}G[maxn];
int head[maxn]; int num;
int du[maxn];int n,m;
int ans[maxn];
void add(int u,int v)
{
    G[++num].v=v;G[num].nxt=head[u];head[u]=num;
}
int tuopu()
{
    queue<int>q;
   // printf("n;%d m:%d\n",n,m);
    for(int i=1;i<=n;i++){
        if(!du[i])
            q.push(i);
    }
    int cot=0;
    while(!q.empty()){
        int u=q.front();
      //  printf("u:%d\n",u);
        q.pop();
        cot++;
        ans[u]=cot;
        for(int i=head[u];i;i=G[i].nxt){
            int v=G[i].v;
            du[v]--;
            if(!du[v]) q.push(v);
        }
    }
   // printf("cot:%d\n",cot);
    if(cot==n) return 1;
    else return 0;
}
void init()
{
    memset(head,0,sizeof(head));
    num=0;
    memset(du,0,sizeof(du));
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a[i].op,&a[i].u,&a[i].v);
            if(a[i].op==1){
                add(a[i].u,a[i].v);
                du[a[i].v]++;
            }
        }
        int flag=tuopu();
       // printf("flag:%d\n",flag);
        if(flag==0) printf("NO\n");
        else{
            printf("YES\n");
            for(int i=1;i<=m;i++){
                if(a[i].op==1){
                    printf("%d %d\n",a[i].u,a[i].v);
                }
                else{
                    if(ans[a[i].u]<ans[a[i].v]){
                        printf("%d %d\n",a[i].u,a[i].v);
                    }
                    else printf("%d %d\n",a[i].v,a[i].u);
                }
            }
        }
    }
    return 0;
}
扫描二维码关注公众号,回复: 11447158 查看本文章

猜你喜欢

转载自www.cnblogs.com/pangbi/p/13380305.html