图论之拓扑排序各种写法
图的存储主要有邻接矩阵与邻接表两种写法,其中邻接表多采用vector<Edge> edge[N]方式模拟单链表简化存储。
struct Edge
{
int nextNode;//下一个节点编号
int cost;//该边权重
};
vector<Edge> edge[N];//为每个节点都模拟一个单链表
//清空,添加,遍历,删除
edge[i].clear();
edge[i].push_back();
for(int i=0;i<edge[2].size();i++){};
edge[2].erase(edge[2].begin()+i,edge[2].begin()+i+1);//删除edge[2][i]
BFS拓扑:
vector<int> edge[501];
queue<int> Q;//入度为0的节点队列
int inDegree[501];
init();//初始化,读入邻接表
while(Q.empty()==false)Q.pop();//清空上一组测试遗留数据
for(int i=0;i<n;i++)
{
if(inDegree[i]==0)Q.push(i);
}
int cnt=0;
while(Q.empty()==false)
{
int nowP=Q.front();
Q.pop();
cnt++;
for(int i=0;i<edge[nowP].size();i++)
{
inDegree[edge[nowP][i]]--;
if(inDegree[edge[nowP][i]]==0)
Q.push(edge[nowP][i]);
}
}
if(cnt==n)puts("DAG");
else puts("circle");
DFS+stack拓扑:
vector<int> Edge[N];//假设无权值
int vis[N],top=0,stack[N];
void topo_sort(int x) {
vis[x] = 1;
for(int i=0;i<Edge[x].size();i++)
{
if(vis[Edge[x][i]] == 0)
topo_sort(Edge[x][i]);
}
stack[top++] = Edge[x][i];
}
此时的stack也可用链表头插法,两者等价,作用为转化逆拓扑序列。
附:邻接表的写法也有采用数组的与vector模拟单链表类似,代码如下:
int head[N];//child正向
vector<int> p[maxn];//parent反向
struct Edge
{
int to;
int next;
}edge[MAXN];
int cnt=0;
void addEdge(int u,int v)
{
edge[cnt].to = v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
memset(inDegree,0,sizeof(inDegree));
for(int i = 0; i <= n; i++) p[i].clear();
}
//添加
addedge(u,v); //child正向
p[v].push_back(u); //parent反向
inDegree[v]++; //indegree
//遍历
for(int i = head[u]; i != -1; i = edge[i].next){};

浙公网安备 33010602011771号