每次都是把入度为0的点输出,当然输出之后会更新其他点的入度
样例
6 8
a b
a c
a d
c b
c d
d e
f d
f e
输出
a c b f d e
首先看一下我的暴力数组怎么做的吧,我相信你一样就能看懂
程序代码:
#include<stdio.h>
int a[110][110],b[110];
int main()
{
char x,y;
int i,j,k,n,m;
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
{
scanf(" %c %c",&x,&y);
a[x-'a'][y-'a']++;
b[y-'a']++;
}
for(k=0;k<n;k++)
{
for(i=0;i<n;i++)
if(b[i]==0)
{
printf("%c ",i+'a');
b[i]--;
break;
}
if(i==n)
break;
for(j=0;j<n;j++)
if(a[i][j]>0)
b[j]--;
}
return 0;
}
刚刚的数组暴力有点浪费时间,其实我们只需用一个队列把入度为0的点存起来就行了,然后直接跑入度为0的点,更新与该点相连的点即可,当然了,很多时候要求输出按字典序什么的,这里用了优先队列
优先队列默认为是从大到小排序的,容器用的是vector
程序代码:
#include<stdio.h>
#include<queue>
using namespace std;
int a[110][110],b[110];
int main()
{
priority_queue<int,vector<int>,greater<int> >q;//greater<int> 后有一个空格
char x,y;
int A;
int i,n,m;
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
{
scanf(" %c %c",&x,&y);
a[x-'a'][y-'a']++;
b[y-'a']++;
}
for(i=0;i<n;i++)
if(b[i]==0)
q.push(i);
while(!q.empty())
{
A=q.top();
q.pop();
printf("%c ",A+'a');
for(i=0;i<n;i++)
if(a[A][i]>0)
{
b[i]--;
if(b[i]==0)
q.push(i);
}
}
return 0;
}
如果需要判断是否满足拓扑排序,或者是否有环,定义一个数组,来存出来的入度为0的点,如果点数和为n则符合,反正不符