题目大意:
给出n(代表有n个任务),m组二元组u和v,表示u小于v。求一个从大到小排列的数组。
题目链接:(https://vjudge.net/problem/UVA-10305)
分析:
用拓扑排序,拓扑排序的思路简述如下:
(一)状态标记:共三种,-1表示访问中,0表示未访问,1表示已访问,由数组vis保存
(二)dfs终止的判别条件:如果存在环,则不存在,退出;反之把当前结点加入拓扑排序的首部(线性序列的当前第一个位置,随着排序的进行,这个位置会不断前移)
(三)通过数组res记录拓扑排序,记住一定要逆序记录
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int res[1005],pos,vis[1005],n,m,Map[105][105];
//dfs步骤
void dfs(int u)//判断结点u
{
vis[u]=-1;//-1代表正在进行访问
for(int i=1;i<=n;i++)
if(Map[u][i]&&!vis[i])//如果u与i存在二元组,并且i没有被遍历过
dfs(i);
vis[u]=1;//1代表访问结束
res[pos]=u;//把u加进去
pos--;
}
int main()
{
while(cin>>n>>m&&(m||n))
{
pos=n;
memset(vis,0,sizeof(vis));
//读取数据,初始化
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
Map[u][v]=1;
}
//遍历
for(int i=1;i<=n;i++)
if(!vis[i])
dfs(i);
//输出
cout<<res[1];
for(int i=2;i<=n;i++)
cout<<" "<<res[i];
cout<<endl;
}
}