Graph storage method + union search topological sorting template

Table of contents

Common storage methods for graphs

1. Adjacency matrix

2. Adjacency list

3. Chain forward star

4. Vector storage (my favorite)

And lookup

1. Union check template

2. Check and set example questions

topological sort

1. Topological sort template

2. Topological sorting example


Common storage methods for graphs

Details: Several storage methods for graphs_roadkiller.'s blog-CSDN blog_Graph storage methods     

1. Adjacency matrix

int map[maxn][maxn];
map[i][j]=w	//表示第i个顶点到第j个顶点有权值为w的边

2. Adjacency list

struct edgeNode
{
	int adjvex;//点
	int w;	   //权值
	struct edgeNode* next;//指向下一条边
};

struct edge
{
	int start;//起点
	int to;   //终点
	int cost; //权值
};

3. Chain forward star

struct edge
{
	int to;   //当前边的终点
	int w ;   //权值 
	int next  //下一条边的下标   
};

4. Vector storage (my favorite)

vector<int>edge[maxn];
//edge[n][i-1]表示第n个节点第i条边连接的顶点
//edge[n].size()表示与第n个节点相连的顶点数(边数)

And lookup

1. Union check template

void init()            //初始化
{
	for (int i = 1; i <= n; i++)
		fa[i] = i;
}

int find(int x)        //查找
{
	if (fa[x] == x)
		return x;
	else
	{
		fa[x] = find(fa[x]);
		return fa[x];
        //=return fa[x]=find(fa[x])
        //路径压缩
	}
}

void unions(int x,int y)//合并
{
	int fa_x = find(x);
	int fa_y = find(y);
	fa[fa_x] = fa_y;
}

2. Check and set example questions

Pocket Sky (Luogu P1195)

Title description: There are relationships between n clouds and m clouds, find the minimum cost required to connect k marshmallows

Input: three numbers n, m, k in the first line, and three numbers x, y, l in each line of m lines, indicating that x cloud and y cloud can be connected by the cost of l

Output: minimum cost, if not "No Answer"

Analysis: use union search, first sort the edge nodes according to weight, connect 1 tree needs n-1 edges, connect k trees need nk edges

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

int n, m, k;
int x, y, l;

struct Node
{
	int x, y, l;
}node[10010];

bool cmp(Node& a, Node& b)
{
	return a.l < b.l;
}

int fa[1005];

void init()
{
	for (int i = 1; i <= n; i++)
		fa[i] = i;
}

int find(int x)
{
	if (fa[x] == x)
		return x;
	else
		return fa[x]=find(fa[x]);
}

void unions(int x, int y)
{
	int fa_x = find(x);
	int fa_y = find(y);
	fa[fa_x] = fa_y;
}

int ans = 0;
int sum;

int main()
{
	cin >> n >> m >> k;

	for (int i = 1; i <= m; i++)
	{
		cin >> node[i].x >> node[i].y >> node[i].l;
	}

	init();


	sort(node + 1, node + m + 1, cmp);

	for (int i = 1; i <= m; i++)
	{
		if (find(node[i].x) != find(node[i].y))
		{
			unions(node[i].x, node[i].y);
			ans += node[i].l;
			sum++;
		}
		if (sum == n - k)
		{
			cout << ans;
			return 0;
		}
	}

	cout << "No Answer";
}

topological sort

1. Topological sort template

The graph is stored in vector, and the queue implements topo:

#include<iostream>
#include<queue>
#include<vector>
#define maxn 1000

using namespace std;

int in[maxn],int out[maxn];//入度,出度数组

vector<int>edge[maxn];//edge[n][0]表示第n个节点第一条边连接的节点
vector<int>ans;//拓扑序列

queue<int>q;

int main()
{
	for (int i = 0; i < n; i++)//寻找入度为0节点入队
		if (in[i] == 0)
			q.push(i);

	while (!q.empty())      //循环出队并判断,直到找不到入度为0的节点
	{
		int p = q.front();
		q.pop();            //出队
		ans.push_back(p);   //加入拓扑序列
		for (int i = 0; i < edge[p].size(); i++)
		{   //将与之相连的节点入度-1
			in[edge[p][i]]--;
			if (in[edge[p][i] == 0])
				q.push(edge[p][i]);
		}
	}

	if (ans.size() == n)    //所有节点入拓扑序列,即无环
	{
		for (int i = 0; i < ans.size(); i++)
			cout << ans[i] << " ";
	}
	else
		cout << "No Answer";
}

2. Topological sorting example

Maximum food chain count (Luogu P4017)

Title description: Find the maximum number of food chains in the food web

Input: the number of biological species n in the first line, the relationship coefficient m, and two positive integers in each line of the next m lines, indicating A being eaten and B eating A

Output: an integer, which is the result of modulo 8011200280112002 on the maximum number of food chains

Analysis: Refer to  Luogu P4017 Maximum Food Chain Counting Solution - Royal·Dragon - 博客园

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define maxn 5005

using namespace std;

int n, m;
const int mod = 80112002;

int in[maxn],out[maxn];
vector<int>edge[maxn];
int num[maxn];//记录到每个点的路径数

queue<int>q;
int ans;

int main()
{
	cin >> n >> m;
	int x, y;

	for (int i = 1; i <= m; i++)//存图
	{
		cin >> x >> y;
		++in[y], ++out[x];
		edge[x].push_back(y);
	}

	for (int i = 1; i <= n; i++)//寻找入度为0节点
	{
		if (!in[i])
		{
			num[i] = 1;
			q.push(i);
		}
	}

	while (!q.empty())
	{
		int f = q.front();
		q.pop();
		for (int i = 0; i < edge[f].size();i++)
		{
			int next = edge[f][i];
			--in[next];
			num[next] = (num[next] + num[f]) % mod;
			if (in[next] == 0)
			{
				q.push(next);
			}
		}
	}

	for (int i = 1; i <= n; i++)
	{
		if (!out[i])
		{
			ans = (ans + num[i]) % mod;
		}
	}
	cout << ans;
}

Guess you like

Origin blog.csdn.net/skycol/article/details/124632098