晕牛【拓扑排序】【BFS】
题目大意:
4 2 3
1 2
4 3
1 3
4 2
3 2
1 3
2 4
2 3
思路:
好题好题!
拓扑排序真的是一个轻轻松松学会的算法。
我们将单向道路按照拓扑排序排一下,然后读入双向边,将排在前面的指向排在后面的,输出,就。。。
AC了!
具体原理我也不太清楚,还是去问那个某dalao吧。
代码:
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
int n,m1,m2,x,y,tot,head[300001],vis[300001],num[300001],t[300001],o[300001];
struct edge
{
int next,to;
}e[300001];
void fre()
{
freopen("dizzy.in","r",stdin);
freopen("dizzy.out","w",stdout);
}
void add(int from,int to)
{
tot++;
e[tot].to=to;
e[tot].next=head[from];
head[from]=tot;
}
void bfs()
{
int k=0;
queue<int> q; //队列
for (int i=1;i<=n;i++)
if (!num[i]) //没有入度
{
q.push(i); //加入队列
t[++k]=i; //记录
}
do
{
int u=q.front();
q.pop();
for (int i=head[u];i;i=e[i].next) //邻接表
{
int v=e[i].to;
num[v]--; //入度减一
if (!num[v]) //没有入度
{
q.push(v); //入队
t[++k]=v;
}
}
}
while (q.size());
}
int main()
{
fre();
scanf("%d%d%d",&n,&m1,&m2);
for (int i=1;i<=m1;i++)
{
scanf("%d%d",&x,&y);
num[y]++; //求最大入度,为拓扑排序初始化
add(x,y); //邻接表
}
bfs();
for (int i=1;i<=n;i++)
o[t[i]]=i;
for (int i=1;i<=m2;i++)
{
scanf("%d%d",&x,&y);
if (o[x]<o[y]) printf("%d %d\n",x,y); //O(1)输出
else printf("%d %d\n",y,x);
}
return 0;
}