Table of contents
Common storage methods for graphs
4. Vector storage (my favorite)
2. Check and set example questions
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;
}