混合图 (Standard IO)
Description
有一张N个点,M1条有向边,M2条无向边组成的混合图。询问一个给所有无向边定向的方案。使得最终的图中没有环。保证一定有解。
Input
第一行,三个数字N,M1,M2。
接下来M1+M2行,每行两数字Ai,Bi。表示一条边。
前M1条是有向边。方向是Ai到Bi。
Output
输出M2行,按输出顺序输出为无向边确定的方向。Ai Bi或Bi Ai。
有多解时输出任意解。
题解
对原图做拓扑排序,得到每个点的入队时间,加边的时候把边定向为从入队时间早的点到晚的点,原来的入队顺序就依然成立,就无环了。
代码
type
arr=record
y,next:longint;
end;
var
n,nm,m1,m2:longint;
e:array [0..400001] of arr;
ls,f,q,b,h:array [0..200001] of longint;
procedure add(x,y:longint);
begin
inc(nm);
e[nm].y:=y;
e[nm].next:=ls[x];
ls[x]:=nm;
end;
procedure topsort;
var
he,ta,i,t,v:longint;
begin
he:=1; ta:=0;
for i:=1 to n do
if f[i]=0 then
begin
inc(ta);
q[ta]:=i; b[i]:=1;
end;
while he<=ta do
begin
t:=q[he];
i:=ls[t];
while i<>0 do
begin
v:=e[i].y;
dec(f[v]);
if f[v]=0 then
begin
inc(ta);
q[ta]:=v; b[v]:=1;
end;
i:=e[i].next;
end;
inc(he);
end;
end;
procedure init;
var
i,u,v:longint;
begin
readln(n,m1,m2);
nm:=0;
for i:=1 to m1 do
begin
readln(u,v);
add(u,v);
inc(f[v]);
end;
topsort;
for i:=1 to n do
h[q[i]]:=i;
for i:=1 to m2 do
begin
readln(u,v);
if h[u]<h[v] then writeln(u,' ',v)
else writeln(v,' ',u);
end;
end;
begin
init;
end.