混合图_纪中3061_拓扑排序

Description


有一张N个点,M1条有向边,M2条无向边组成的混合图。询问一个给所有无向边定向的方案。使得最终的图中没有环。保证一定有解。

Input


第一行,三个数字N,M1,M2。

接下来M1+M2行,每行两数字Ai,Bi。表示一条边。

前M1条是有向边。方向是Ai到Bi。

Output


输出M2行,按输出顺序输出为无向边确定的方向。Ai Bi或Bi Ai。

有多解时输出任意解。

Data Constraint


[数据范围]

1<=N<=100 000
1<=M1,M2<=100 000

Analysis


对有向边作拓扑排序并记录点的拓扑序
对于一个环,只可能是一条有向边从拓扑序靠后的点连向了拓扑序靠前的点
对每条无向边判断一下两点的拓扑序大小关系,输出就好了
比赛想到了正解但是写错了qaq

Code


#include <stdio.h>
#include <queue>
using namespace std;
struct edge
{
    int x,y,next;
};
queue<int>q;
edge e[350001];
int ind[150001],ls[150001],t[150001];
int maxE=0,cnt=0;
void add(int x,int y)
{
    e[++maxE]=(edge){x,y,ls[x]};
    ls[x]=maxE;
}
void topsort()
{
    while (!q.empty())
    {
        int now=q.front();q.pop();
        for (int i=ls[now];i;i=e[i].next)
            if (!(--ind[e[i].y]))
                q.push(e[i].y),t[e[i].y]=++cnt;
    }
}
int main()
{
    int n,a,b,x,y;
    scanf("%d%d%d",&n,&a,&b);
    for (int i=1;i<=a;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        ++ind[y];
    }
    for (int i=1;i<=n;i++)
        if (!ind[i])
            q.push(i),t[i]=++cnt;
    topsort();
    for (int i=1;i<=b;i++)
    {
        scanf("%d%d",&x,&y);
        if (t[x]<t[y])
            printf("%d %d\n",x,y);
        else
            printf("%d %d\n",y,x);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值