Codeforces Round #656 (Div. 3) E. Directing Edges 题解(拓扑找环)

题目链接

题目大意

给你一个图有n个点和m条边,其中m条边有的是有向边,有的是无向边,看你是否能把所有无向边变为有向边,然后使这个图无环,如果没环,那么输出YES,并且输出所有边的方向,否则输出NO

题目思路

自己想到拓扑排序那方面了,但是还是没写出来,看大佬的博客说是套路题qwq

首先有向边是不能修改的,直接把有向边连起来,拓扑找环看是否能够构成环,如果能直接输出NO,否则就是YES,为什么是YES呢,因为你可以把所有点都弄一下拓扑序(不知道是不是这么叫),然后你把无向边按拓扑序小的连拓扑序大的就行了,而有向边显然本身就是如此。画个图演示一下就懂了

代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define debug printf("I am here\n");
using namespace std;
typedef long long ll;
const int maxn=2e5+5,mod=2147493647,inf=0x3f3f3f3f;
int t,n,m,deg[maxn],head[maxn],cnt,tot,pos[maxn];
struct node{
    int to,next;
}e[maxn<<1];
vector<pair<int,int> > vec;
queue<int> que;
void init(){
    vec.clear();
    cnt=tot=0;
    for(int i=1;i<=n;i++){
        pos[i]=deg[i]=head[i]=0;
    }
}
void add(int u,int v){
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        init();
        for(int i=1,w,u,v;i<=m;i++){
            scanf("%d%d%d",&w,&u,&v);
            vec.push_back({u,v});
            if(w==1){//把有向边加进来
                add(u,v);
                deg[v]++;
            }
        }
        for(int i=1;i<=n;i++){//拓扑找环
            if(deg[i]==0){
                que.push(i);
            }
        }
        while(!que.empty()){
            int x=que.front();
            que.pop();
            pos[x]=++tot;
            for(int i=head[x];i;i=e[i].next){
                deg[e[i].to]--;
                if(deg[e[i].to]==0){
                    que.push(e[i].to);
                }
            }
        }
        if(tot!=n){//有环
            printf("NO\n");
        }else{
            printf("YES\n");
            for(int i=0;i<vec.size();i++){
                if(pos[vec[i].fi]>pos[vec[i].se]){
                    swap(vec[i].fi,vec[i].se);
                }
                printf("%d %d\n",vec[i].fi,vec[i].se);
            }
        }
    }
    return 0;
}


你可能感兴趣的:(图论)