这两天看了拓扑排序,水了若干题,记录一发。
大概就是记录有向图,和每个点的入度,每次取出一个入度为零的点,并修改以该点为起点的有向边的终点的入度。不断重复以上步骤,直到:
1.取完所有点。此时完成排序。
2.没有入度为0的点,但还有点没取。此时说明图中存在环,非DAG。
自写渣渣模板如下:
int G[maxn][maxn];
int ans[maxn];
int indegree[maxn];
bool vis[maxn];
int n;
void toposort()
{
memset(vis,false,sizeof(vis));
for(int st=0;st<n;st++)
{
int rec;
for(int i=0;i<n;i++)
{
if(!vis[i]&&!indegree[i])
{
rec=i;
}
}
vis[rec]=true;
for(int j=0;j<n;j++)
{
if(G[rec][j])indegree[j]--;
}
}
return;
}
其间可以统计入度为零的点的个数,当且仅当每次入度为零的点唯一,拓扑序唯一。(poj1094)
同时,若要得出所有而非字典序第一的拓扑序,可以将toposort改成递归形式(类似dfs的回溯),每次将所有入度为零的点都讨论一遍即可。(poj1270)