初识-图论基础+拓扑排序的实现
目录
初识-图论基础+拓扑排序的实现
图的存储和表示
方法一:邻接矩阵
-
g[i][j]=1
表示点i和点j是连通的 -
无向图:
g[i][j]=1
并且g[j][i]=1
-
有向图:
g[i][j]=1
只考虑单一的位置 -
缺点:会花费n*n的空间,当n很大的时候,花费量会变得巨大
另外,由于某点到本身的连接时是没有意义的,因而,会浪费一定的空间
方法二:用变长数组来实现邻接矩阵
- 理解:就好像是一条上面绑着多个正在生产肽链的核糖体的mRNA
图论基本知识
度
度是无向图的概念,表示该点连接的边数
入度
入度是有向图的概念,表示从该点指向其他点的边的数量
出度
出度是有向图的概念,表示从其他点流向该点的边的数量
图论的初步应用
拓扑排序
找到入度为0且在某种意义上可以理解成是排在所有点的前面的点输出到某个数组中,并不断重复直至所有点被清空
步骤
- 点和点的储存:邻接表+有向图
- 首先从小到大寻找入度为0的点进行输出。
- 从小到大寻找是为了保证题目对顺序的需求。
- 入度为0说明该点前面没有其他的点,也就意味着该点是排在最前面的点之一。
- 去除已经加入答案数组的点与仍未加入答案数据的点的联系。
UVA10305 给任务排序 Ordering Tasks
[转载自海岛blog]https://blog.csdn.net/tigerisland45/article/details/81122394
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int g[101][101];
int ans[101];
int degreein[101];
int n,m;
void Topological_Sorting()
{
int i,j;
for(i=1;i<=n;i++)
{
int k=1;
while(degreein[k]!=0)
{
k++;
}
degreein[k]=-1;
ans[i]=k;
for(j=1;j<=n;j++)
{
if(g[k][j])
{
degreein[j]--;
}
}
}
}
int main()
{
int u,v;
int i;
while(~scanf("%d%d", &n, &m) && (n || m))
{
// 初始化
memset(g, 0, sizeof(g));
memset(degreein, 0, sizeof(degreein));
memset(ans, 0, sizeof(ans));
// 读入数据
int u, v;
for(i = 1; i <= m; i++)
{
scanf("%d%d", &u, &v);
g[u][v] = 1;
degreein[v]++;
}
Topological_Sorting();
for(i=1;i<=n-1;i++)
{
printf("%d ",ans[i]);
}
printf("%d\n",ans[n]);
}
return 0;
}