拓扑排序-Kahn算法

拓扑排序-Kahn算法

该算法的关键在于需要维护一个入度为0的顶点的集合:

每次从该集合中取出(如果要求输出时编号小的在前,可以用优先队列保存集合)一个顶点,将该顶点放入保存结果的List中。

紧接着循环遍历由该顶点引出的所有边,从图中移除这条边,同时获取该边的另外一个顶点,如果该顶点的入度在减去本条边之后为0,那么也将这个顶点放到入度为0的集合中。然后继续从集合中取出一个顶点…………

 

当集合为空之后,检查图中是否还存在任何边,如果存在的话,说明图中至少存在一条环路。不存在的话则返回结果List,此List中的顺序就是对图进行拓扑排序的结果。

 

题目链接:确定比赛名次(HDU - 1285 

 

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#define INF 1<<29
using namespace std;
int in[510],n,m;
bool vis[510];
vector<int> vec[510];
void bfs()
{
    //优先队列存储,保证输出时编号小的靠前
    priority_queue<int,vector<int>,greater<int> > q;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
    {
        if(!in[i])//首先将入度为0的点入队(即没有前驱的顶点)
        {
            q.push(i);
            vis[i]=1;
        }
    }
    int flag=0;
    while(!q.empty())
    {
        int top=q.top(); q.pop();//取出top
        
        if(flag)
            printf(" ");//输出
        printf("%d",top);
        flag=1;
        
        for(int i=0;i<vec[top].size();i++)
        {
            int now=vec[top][i];
            in[now]--;//将top的所有直接后继顶点入度-1
            if(!vis[now] && !in[now])//如果这个顶点的入度为0,将它入队
            {
                vis[now]=1;
                q.push(now);
            }
        }
    }
    printf("\n");
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int u,v;
        memset(in,0,sizeof(in));
        for(int i=1;i<=n;i++)
            vec[i].clear();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&u,&v);
            vec[u].push_back(v);
            in[v]++;//v的入度加一
        }
        bfs();
    }
    return 0;
}

 

以下是用C语言实现拓扑排序Kahn算法和DFS算法的示例代码: 1. 拓扑排序Kahn算法: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 struct Node { int data; struct Node* next; }; struct Graph { int numVertices; struct Node** adjLists; int* indegree; }; struct Node* createNode(int data) { struct Node* newNode = malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } struct Graph* createGraph(int vertices) { struct Graph* graph = malloc(sizeof(struct Graph)); graph->numVertices = vertices; graph->adjLists = malloc(vertices * sizeof(struct Node*)); graph->indegree = malloc(vertices * sizeof(int)); int i; for (i = 0; i < vertices; i++) { graph->adjLists[i] = NULL; graph->indegree[i] = 0; } return graph; } void addEdge(struct Graph* graph, int src, int dest) { struct Node* newNode = createNode(dest); newNode->next = graph->adjLists[src]; graph->adjLists[src] = newNode; graph->indegree[dest]++; } void topologicalSort(struct Graph* graph) { int* result = malloc(graph->numVertices * sizeof(int)); int front = 0, rear = 0; int* indegree = graph->indegree; int i; for (i = 0; i < graph->numVertices; i++) { if (indegree[i] == 0) { result[rear++] = i; } } while (front != rear) { int currentVertex = result[front++]; struct Node* temp = graph->adjLists[currentVertex]; while (temp) { int adjVertex = temp->data; indegree[adjVertex]--; if (indegree[adjVertex] == 0) { result[rear++] = adjVertex; } temp = temp->next; } } if (rear != graph->numVertices) { printf("Graph contains a cycle!\n"); return; } printf("Topological Sort:"); for (i = 0; i < graph->numVertices; i++) { printf(" %d", result[i]); } printf("\n"); } int main() { int vertices, edges; printf("Enter the number of vertices: "); scanf("%d", &vertices); printf("Enter the number of edges: "); scanf("%d", &edges); struct Graph* graph = createGraph(vertices); int i, src, dest; for (i = 0; i < edges; i++) { printf("Enter edge %d (source destination): ", i+1); scanf("%d %d", &src, &dest); addEdge(graph, src, dest); } topologicalSort(graph); return 0; } ``` 2. 拓扑排序的DFS算法: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 struct Node { int data; struct Node* next; }; struct Graph { int numVertices; struct Node** adjLists; int* visited; }; struct Node* createNode(int data) { struct Node* newNode = malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } struct Graph* createGraph(int vertices) { struct Graph* graph = malloc(sizeof(struct Graph)); graph->numVertices = vertices; graph->adjLists = malloc(vertices * sizeof(struct Node*)); graph->visited = malloc(vertices * sizeof(int)); int i; for (i = 0; i < vertices; i++) { graph->adjLists[i] = NULL; graph->visited[i] = 0; } return graph; } void addEdge(struct Graph* graph, int src, int dest) { struct Node* newNode = createNode(dest); newNode->next = graph->adjLists[src]; graph->adjLists[src] = newNode; } void DFS(struct Graph* graph, int vertex, int* result, int* index) { struct Node* adjList = graph->adjLists[vertex]; graph->visited[vertex] = 1; while (adjList) { int connectedVertex = adjList->data; if (!graph->visited[connectedVertex]) { DFS(graph, connectedVertex, result, index); } adjList = adjList->next; } result[(*index)++] = vertex; } void topologicalSort(struct Graph* graph) { int* result = malloc(graph->numVertices * sizeof(int)); int index = 0; int i; for (i = 0; i < graph->numVertices; i++) { if (!graph->visited[i]) { DFS(graph, i, result, &index); } } printf("Topological Sort:"); for (i = graph->numVertices - 1; i >= 0; i--) { printf(" %d", result[i]); } printf("\n"); } int main() { int vertices, edges; printf("Enter the number of vertices: "); scanf("%d", &vertices); printf("Enter the number of edges: "); scanf("%d", &edges); struct Graph* graph = createGraph(vertices); int i, src, dest; for (i = 0; i < edges; i++) { printf("Enter edge %d (source destination): ", i+1); scanf("%d %d", &src, &dest); addEdge(graph, src, dest); } topologicalSort(graph); return 0; } ``` 这些代码可以帮助您实现拓扑排序Kahn算法和DFS算法。您可以根据需要进行修改和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值