邻接表法存图与链式前向星法存图

邻接表法

邻接表就是用vector来进行存放的
代码实现(以无向图为例)

vector <int > e[ MAXN ]; // edge
vector <int > v[ MAXN ]; // val
cin >>a>>b>>c;
e[a]. push_back (b);
v[a]. push_back (c);
e[b]. push_back (a);
v[b]. push_back (c);

无权图的邻接表法存图例题

树的直径

一棵树的直径就是这棵树上存在的最长路径。现在有一棵n个节点的树,现在想知道这棵树的直径包含的边的个数是多少?
如图所示的数据,这棵树的直径为(1-2-3-6-9)这条路径,包含的边的个数为4,所以答案是4。
邻接表法存图与链式前向星法存图_第1张图片

输入
第1行:一个整数n,表示树上的节点个数。(1<=n<=100000)
第2-n行:每行有两个整数u,v,表示u与v之间有一条路径。(1<=u,v<=n)

输出
输出一个整数,表示这棵树直径所包含的边的个数。

输入样例
10
1 2
2 3
3 4
3 5
3 6
3 7
3 10
6 8
6 9

输出样例
4

代码

#include
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+10;
vector<int> v[maxn];
int n,a,b,ans;
int dis[maxn],vis[maxn];
int bfs(int x)
{
	memset(vis,0,sizeof(vis));
	memset(dis,0,sizeof(dis));
	queue<int> q;
	q.push(x);vis[x]=1;
	int point=0;
	while(!q.empty())
	{
		int mid=q.front();
		q.pop();
		if(dis[mid]>ans)
		{
			ans=dis[mid];
			point=mid;
		}
		for(int i=0;i<v[mid].size();i++)
		{
			if(!vis[v[mid][i]])
			{
				vis[v[mid][i]]=1;
				dis[v[mid][i]]=dis[mid]+1;
				q.push(v[mid][i]);
			}
		}
	}
	return point;
}
int main()
{
	cin>>n;
	for(int i=1;i<n;i++)
	{
		cin>>a>>b;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	ans=0;
	int point=bfs(1);
	ans=0;
	bfs(point);
	cout<<ans<<endl;
	return 0;
}

带权图的的邻接表法存图例题

带权图用vector数组存pair,pair存储的是节点和权值

Cow Marathon
After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has committed to create a bovine marathon for his cows to run. The marathon route will include a pair of farms and a path comprised of a sequence of roads between them. Since FJ wants the cows to get as much exercise as possible he wants to find the two farms on his map that are the farthest apart from each other (distance being measured in terms of total length of road on the path between the two farms). Help him determine the distances between this farthest pair of farms.
有n个农田和m条路,以及每条路的方向(方向在这道题中没有用),求最长的一条路,也就是两点间的最大距离,即树的直径.
Input

  • Lines 1…: Same input format as “Navigation Nightmare”.
    Output
  • Line 1: An integer giving the distance between the farthest pair of farms.
    Sample Input
    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    Sample Output
    52
    Hint
    The longest marathon runs from farm 2 via roads 4, 1, 6 and 3 to farm 5 and is of length 20+3+13+9+7=52.

代码

#include
#include
#include
#include
#include
using namespace std;
int N,M,X,Y,Z,ans;
int dis[40020];
bool vis[40020];
vector<pair<int,int> >V[40020];
int bfs(int n){
	memset(dis,0,sizeof(dis));
	memset(vis,0,sizeof(vis));
	queue<int>Q;
	Q.push(n);
	vis[n]=1;
	ans=0;
	int point=0,t;
	while(!Q.empty()){
		t=Q.front();
		Q.pop();
		if(dis[t]>ans){
			ans=dis[t];
			point=t;
		}
		for(int i=0;i<V[t].size();i++){	
			if(vis[V[t][i].first]==0){			//判断改点是否被访问过
				vis[V[t][i].first]=1;
				dis[V[t][i].first]=dis[t]+V[t][i].second;	//将到该点之前经过的所有边的权值相加
				Q.push(V[t][i].first);
			}
		}
	}
	return point;
}
int main(){
	scanf("%d%d",&N,&M);
	for(int i=0;i<M;i++){
		scanf("%d%d%d %*c",&X,&Y,&Z);
		V[X].push_back(make_pair(Y,Z));
		V[Y].push_back(make_pair(X,Z));
	}
	bfs(bfs(1));
	printf("%d\n",ans);
	return 0;
}

链式前向星存图

感觉这个博主讲的比较详细
https://blog.csdn.net/qq_41754350/article/details/81082728
还有这些
https://blog.csdn.net/sugarbliss/article/details/86495945
https://blog.csdn.net/qq_40623603/article/details/84799261
https://blog.csdn.net/sjs_caomei/article/details/82181607

用链式前向星存图的例题

Cow Marathon(同上题)
After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has committed to create a bovine marathon for his cows to run. The marathon route will include a pair of farms and a path comprised of a sequence of roads between them. Since FJ wants the cows to get as much exercise as possible he wants to find the two farms on his map that are the farthest apart from each other (distance being measured in terms of total length of road on the path between the two farms). Help him determine the distances between this farthest pair of farms.
有n个农田和m条路,以及每条路的方向(方向在这道题中没有用),求最长的一条路,也就是两点间的最大距离,即树的直径.
Input

  • Lines 1…: Same input format as “Navigation Nightmare”.
    Output
  • Line 1: An integer giving the distance between the farthest pair of farms.
    Sample Input
    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    Sample Output
    52
    Hint
    The longest marathon runs from farm 2 via roads 4, 1, 6 and 3 to farm 5 and is of length 20+3+13+9+7=52.

代码

//Cow Marathon
#include 
#include 
#include 
#include 
#include 
#define maxn 100000
using namespace std;
int head[maxn];		//存放边的头部
int dis[maxn];		//存放边的权值
int vis[maxn];		//判断点是否被访问过
int num = 0, sum;
char s;
 
struct node {		//设置一个结构体用于存图
	int to;			//边的起点
	int d;			//权值
	int next;		//边的终点
}edge[maxn];
 
void add(int from,int to,int d) 		//存图
{
	edge[++num].next=head[from];
	edge[num].to=to;
	edge[num].d=d;
	head[from]=num;
}
 
void bfs(int x) {
	queue<int> q;
	memset(dis, 0, sizeof(dis));	//每次调用bfs都要清空
	memset(vis, 0, sizeof(vis));
	vis[x] = 1;
	q.push(x);
	num = x, sum = 0;
	while(!q.empty()) {
		int u = q.front();
		q.pop();
		for(int i = head[u]; i != -1; i = edge[i].next) {
			if(!vis[edge[i].to] && dis[edge[i].to] < dis[u] + edge[i].d) {
				vis[edge[i].to] = 1;
				dis[edge[i].to] = dis[u] + edge[i].d;
				q.push(edge[i].to);
				if(dis[edge[i].to] > sum) {
					sum = dis[edge[i].to];
					num = edge[i].to;
				}
			}
		}
	}
}
 
int main() {
	int a, b, c,n,m;
	memset(head, -1, sizeof(head));
	memset(edge, 0, sizeof(edge));
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d%d%s",&a,&b,&c,&s);
		add(a, b, c);  
		add(b, a, c);
	}
	bfs(1); 
	bfs(num);
	printf("%d\n", sum);
	return 0;
}

你可能感兴趣的:(学习笔记)