Featured image of post 图论+树

图论+树

图?树?

在我们写题目之前我们应该学习一下图和树的存贮方式 1.邻阶矩阵
2.邻接表
3.链式前向星(静态链表)
掌握这些基础的存储方式我们才能解决关于图和树的问题,请各位同学自行学习

`

[p5318查找文献](P5318 【深基18.例3】查找文献 - 洛谷)

题目大意

其实就是给你一张有向图,要你把它深度遍历一遍再广度遍历一遍。

题解

用bfs和dfs遍历

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct edge{       //存边结构体
	int u,v;
}; 
vector <int> e[100001];  
vector <edge> s;
bool vis1[100001]={0},vis2[100001]={0}; //标记数组
void dfs(int x){  //深度优先遍历
	vis1[x]=1;
	cout<<x<<" ";
	for(int i=0;i<e[x].size();i++){
		int point=s[e[x][i]].v;
		if(!vis1[point]){
			dfs(point);
		}
	}
}
void bfs(int x){  //广度优先遍历
	queue <int> q;
	q.push(x);
	cout<<x<<" ";
	vis2[x]=1;
	while(!q.empty()){
		int fro=q.front();
		for(int i=0;i<e[fro].size();i++){
			int point=s[e[fro][i]].v;
			if(!vis2[point]){
				q.push(point); 
				cout<<point<<" ";
				vis2[point]=1;
			}
		}
		q.pop();
	}
}

[B3647 【模板】Floyd](B3647 【模板】Floyd - 洛谷)

题目大意

给n个点和m跳边组成的无向图,求所有(i,j)的最短路径

数据范围

对于 100% 的数据,n≤100,m≤4500,任意一条边的权值 w 是正整数且 1⩽w⩽1000。

题解

Floyd的板子题~~(本质上是动态规划)~~f[i] [j]为i到j的最短路径

本质上是一个三维状态数组f[i] [j] [k]为从i到j期间经过了1到k这些点

1
2
3
4
for(int k=1; k<=n; k++) 
	for(int i=1; i<=n; i++) 
		for(int j=1; j<=n; j++)
			f[i][j]=min(f[i][j],f[i][k]+f[k][j]); 

参考写法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void solve () {
    cin>>n>>m;
	for(int i=1;i<=n;++i)for(int j=1;j<=n;++j){
		if(i==j)dis[i][j]=0;
		else dis[i][j]=INF;
	}
	int v1,v2;ll w;
	for(int i=0;i<m;++i){
		cin>>v1>>v2>>w;
//		dis[v1][v2]=dis[v2][v1]=w;
		//取重边时较小的边 
		dis[v2][v1]=dis[v1][v2]=min(dis[v1][v2],w);
//		dis[v2][v1]=min(dis[v2][v1],w);
	}
	for(int k=1;k<=n;++k){
		for(int i=1;i<=n;++i){
			for(int j=1;j<=n;++j){
				if((i!=j)&&(i!=k)&&(j!=k))
				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
			}
		}
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			if(j>1)cout<<" ";
			cout<<dis[i][j];
		}
		cout<<endl; 
	}
小羊的发癫地方(划掉)
使用 Hugo 构建
主题 StackJimmy 设计