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;
}