John有n个任务要做,每个任务在做之前要先做特定的一些任务。
输入第一行包含两个整数n和m,其中1<=n<=100。 n表示任务数,而m表示有m条任务之间的关系。 接下来有m行,每行包含两个整数i和j,表示任务i要在j之前做。
当读入两个0(i=0,j=0)时,输入结束。
输出包含q行,每行输出一条可行的安排方案。
输入
5 4
1 2
2 3
1 3
1 5
0 0
输出
1 4 2 5 3
需要维护的容器:
1.建图所需要的edge结构体数组,head数组,tot变量
2.队列,入度为0的点需要入队
3.in数组,存i点的入度
4.ans数组,存正确的顺序
代码大体过程:
1.建图
2.先遍历一遍每个点,看入度是否为0,是则入队
3.经典while(!q.empty())循环
取队首,弹出,ans数组加值,遍历与这个点直接相连的所有点,对每个点都需要入度减1,判是否入队
另外如果需要按字典序输出什么的不能用普通队列,用
priority_queue<int, vector<int>, greater<int> > q1;//小根堆
priority_queue<int, vector<int>, less<int> > q2;//大根堆
#include <bits/stdc++.h>
using namespace std;
int n, m;
int a, b;
int tot;
struct node
{
int to, next;
} edge[105];
int head[105];
int in[105];
int ans[105];
priority_queue<int, vector<int>, greater<int> > q;
int now;
void addedge(int u, int v)
{
edge[++tot].to = v;
edge[tot].next = head[u];
head[u] = tot;
in[v]++;
}
void topo()
{
tot = 0;
for(int i = 1; i <= n; ++i) if(!in[i]) q.push(i);
while(!q.empty())
{
now = q.top();
q.pop();
ans[++tot] = now;
for(int i = head[now]; i != -1; i = edge[i].next)
{
in[edge[i].to]--;
if(!in[edge[i].to]) q.push(edge[i].to);
}
}
}
int main()
{
while(~scanf("%d%d", &n, &m) && n + m)
{
memset(head, -1, sizeof(head));
memset(edge, -1, sizeof(edge));
memset(in, 0, sizeof(in));
memset(ans, 0, sizeof(ans));
tot = 0;
for(int i = 1; i <= m; ++i)
{
scanf("%d%d", &a, &b);
addedge(a, b);
}
topo();
for(int i = 1; i <= tot; ++i) printf("%d ", ans[i]);
putchar('\n');
}
return 0;
}