(图论杀我)
定义:
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。(摘自360百科)
其实就是对于一张有向图,按照入度大小从小到大排序。
实现过程:

简单讲就是对于任意状态,先找到一个入度为0的点,记录答案后把所有与它相连的的点的入度减一,重复这个过程即可。
代码:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct edge
{
int next,to;
edge(){}
edge(int a,int b)
{
next=a;
to=b;
}
}e[1000001];
int tot,in[100001],first[100001];//邻接表存图
void add_edges(int a,int b)
{
e[++tot]=edge(first[a],b);
first[a]=tot;
in[b]++;
}
int n,m;
int ans[100001];
queue<int>q;//队列优化
int cnt;
void tp(int n)
{
for(int i=1;i<=n;i++)
{
if(in[i]==0)
q.push(i);
}
while(!q.empty())
{
int p=q.front();//每次找到最后一个入队的点(就是当前状态对应的答案)
q.pop();
ans[cnt++]=p;//存储答案
for(int j=first[p];j;j=e[j].next)
{
in[e[j].to]--;
if(in[e[j].to]==0)
{
q.push(e[j].to);
}
}//删掉改点
}
}
int main()
{
cin>>n>>m;
int A,B;
for(int i=1;i<=m;i++)
{
cin>>A>>B;
add_edges(A,B);
}
tp(n);
for(int i=0;i<n;i++)
{
cout<<ans[i]<<" ";
}
return 0;
}
例题点这里:(拓扑排序+dp) (这个稍微裸一点,小细节很多)
CSP-S RP++!