广搜方式
#include<vector>
#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
#define MAX 100000
int book[MAX],n,indeg[MAX],mp[MAX],k;
vector<int> G[MAX];
void bfs()
{
queue<int>q;
for(int i=1; i<=n; i++)
if(!indeg[i])
q.push(i); //将入度为0的结点入队,入度为0表示,在它之前没有工作或者在它之前的工作已做完
while(!q.empty())
{
int u=q.front();
mp[k++]=u; //记录入度为0的结点顺序
book[u] = 1;
q.pop();
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i];
indeg[v]--; // U已经出队,将与U相连的边减去,即与U相连的结点V的入度减一
if(!indeg[v] && !book[v]) //如果V结点的入度为0,表示前面没有工作,入队
{
book[v]=1;
q.push(v);
}
}
}
}
int main()
{
int s,t,m;
k=0;
scanf("%d%d",&n,&m);
memset(book,0,sizeof(book)); //标记结点是否已被处理
memset(indeg,0,sizeof(indeg)); //将结点的入度全部设为零
for(int i=1; i<=n; i++)
G[i].clear();//一定要清除G[i]中的元素
for(int i=0; i<m; i++)
{
scanf("%d%d",&s,&t);
G[s].push_back(t); //s指向t,s->t,即S工作在t工作之前,t的入度加一
indeg[t]++;
}
bfs();
for(int i=0; i<k; i++)
printf("%d\t",mp[i]);
return 0;
}
/*
eg1:
4 3
1 2
2 3
4 3
eg2:
A->B
B->C
X->B
X->Y
Y->Z
Z->C
输入边(U,V) 即 让U在线性序列中位于V之前,可以理解为 处理V工作之前要先处理工作U
eg2中 ,处理B之前,要先处理A和X
*/
深搜方式:
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAX 100000
int book[MAX],n,k,mp[MAX];
vector<int>G[MAX];
void dfs(int u)
{
book[u]=1;
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i];
if(!book[v])
dfs(v);
}
mp[k++]=u; //如果u的后面没有工作,或者后面的工作已被标记过,加入mp[ ]
}
int main()
{
int s,t,m;
scanf("%d%d",&n,&m);
memset(book,0,sizeof(book));
for(int i=1; i<=n; i++)
G[i].clear();//一定要清除G[i]中的元素
for(int i=0; i<m; i++)
{
scanf("%d%d",&s,&t);
G[s].push_back(t);
}
k=0;
for(int i=1; i<=n; i++)
if(!book[i])
dfs(i); //如果未被标记,dfs
for(int i=k-1; i>=0; i--)
printf("%d\t",mp[i]); //因为深搜是逆向确定各工作的顺序,所以输出时应该从k-1输出
return 0;
}