(图论杀我)
定义:
对一个有向无环图(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++!