传送门HDU1285
拓扑排序+优先队列
注意坑点:输入时需要判断重边,否则入度会出错
#include
using namespace std;
priority_queue<int,vector<int >,greater<int > > q;//升序优先排列
//priority_queue, less >q 为降序排列
//priority q 默认为降序排列 字典序大的为q.top()
const int maxn=510;
bool G[maxn][maxn];
int in[maxn];
int n,m;
void toposort()
{
for(int i=1;i<=n;i++)
if(in[i]==0)
q.push(i);//入度为零压入队列
int c=1;//控制输出格式
while(!q.empty())
{
int v=q.top(); q.pop();//取出队列第一个元素并弹出
if(c!=n)
{
printf("%d ",v);
c++;
}
else
printf("%d\n",v);
for(int i=1;i<=n;i++)//所有与v相关边 入度减一
{
if(G[v][i])
{
in[i]--;
if(!in[i])//入度为零的边 弹入队列
q.push(i);
}
}
}
}
int main()
{
while(cin>>n>>m)
{
memset(in,0,sizeof(in));
memset(G,0,sizeof(G));
while(m--)
{
int a,b;
cin>>a>>b;
if(G[a][b]) continue;
G[a][b]=1;
in[b]++;
}
toposort();
}
return 0;
}
直接法
O(n^2),数据一大就会TLE
#include
using namespace std;
int n,m;
const int maxn=500+10;
int G[maxn][maxn];
int in_degree[maxn];
int ans[maxn];
void topo_sort()
{
int q=0;
int v;
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= n;j ++){
if(!in_degree[j]){
v=j;
ans[q++]=j;
in_degree[j]=-1;
break;
}
}
for(int j = 1;j <= n;j ++)
{
if(G[v][j])
in_degree[j]--;
}
}
}
int main()
{
while(cin>>n>>m)
{
memset(G,0,sizeof(G));
memset(ans,0,sizeof(ans));
memset(in_degree,0,sizeof(in_degree));
int a, b;
for(int i = 1;i <= m;i ++)
{
cin>>a>>b;
if(G[a][b]) continue;
G[a][b]=1;
in_degree[b]++;
}
topo_sort();
for(int i = 0;i < n-1;i ++)
printf("%d",ans[i]);
printf("%d\n",ans[n-1]);
}