今天我们来聊一聊图。(开始爆更)
图是什么?
图是由顶点(vertex、node)和边(edge)组成。顶点的集合是V,边的集合是E,图记为:G=(V,E)。
图分为无向图和有向图两种,在无向图中两个相连的顶点权值应该是只有一个,对于有向图来说,不同方向的权值是不同的,因此就需要用不同的数据存储他们。
图的存储方式
图有两种存储方式,邻接矩阵和邻接表,两者都有优点和缺点。
1.邻接矩阵:
d[i][j]表示的是从i顶点到j顶点的距离,显然自己到本身的距离为0,在无向图中这是一个对称的矩阵
d[i][j]==d[j][i];
d[i][i]==0;
在有向图中,可能不是对称的矩阵,空间的存储花费O(V^2)的空间,不利于稀疏图的存储。这个时候就需要用到邻接表来存储提高空间的利用率。
同时,当出现重边(两个顶点有两条通向的边)或者自环的时候,这个时候也需要用邻接表来存储,当然邻接表的复杂度也相对较高。
2.邻接表:
知识把仅有的边和顶点保存起来,那么空间复杂度就是O(V+E)
那邻接表的缺点是什么呢?就是比邻接矩阵相对复杂,并且如果想要查询两点间是否有边的时候需要遍历整个链表才可以。
邻接表的存储方式
其实方式很多,我比较喜欢用vector
#include <iostream>
#include <vector>
using namespace std;
const int MAX_N=1e5;
vector<int> G[MAX_N];
int mian()
{
int V,E;
cin>>V>>E;
for (int i = 0; i < E; i++)
{
int s,t;
cin>>s>>t;
G[s].push_back(t);
}
return 0;
}
例题:二分图的判定
给定一个具有n个顶点图,要给每个顶点上色,并且要使得相邻的顶点颜色不同。时否能够最多用两种颜色进行染色,保证没有重边和自环。
1<=n<=1000
图着色问题:
相邻顶点染成不同颜色的问题叫做图着色问题。对图进行染色所需要的最小颜色数称为最小着色数。最小着色数是2的图叫做2分图。
对于这道题来说,一旦从某一个顶点出发,将它染成一种颜色,那么相邻的顶点颜色一定是确定的,如果已经涂成了相同的颜色就直接返回false,如果还没有涂色那么就从这个为涂色再出发,先给它涂上另一种颜色再从该点出发去搜索不停地重复这一过程。
初始化
我们需要保存图
const int M=1e3+3;
vector<int> G[M];
输入是点数和边数
int V,E;
我们还需要判断顶点是否染色,我们不需要再开一个数组判断是否可以染色,一开始初始化成0,代表未染色,染色就变成1.这里有一个小技巧,另一种颜色我们如何表示呢?
其实只有两种颜色嘛,可以用1和-1表示最方便,方便查找。搜索参数第一个应该是顶点的编号,还需要该点的涂的颜色,因此用1和-1这样的表示方法最方便
int color[M];
搜索
bool dfs(int v,int c)
{
color[v]=c;//未染色直接染成c
for (int i = 0; i < G[v].size(); i++)
{
if(G[v][i] == c) return false;//同色就说明一定不能成功的
if(G[v][i] == 0 && !dfs(G[v][i],-c)) return false;//没有涂色,就从这个点开始找
}
return true;
}
完整实现
#include <iostream>
#include <vector>
using namespace std;
const int M=1e3+3;
vector<int>G[M];
int color[M];
bool dfs(int v,int c)
{
color[v]=c;
for (int i = 0; i < G[v].size(); i++)
{
if(G[v][i] == c) return false;
if(G[v][i] == 0 && !dfs(G[v][i],-c)) return false;
}
return true;
}
int main()
{
int V,E;
cin>>V>>E;
for (int i = 0; i < E; i++)
{
int s,t;
cin>>s>>t;
G[s].push_back(t);
}
for (int i = 0; i < V; i++)
{
if(color[i] == 0)
{
if(!dfs(i,1))
{
cout<<"No"<<endl;
return 0;
}
}
}
cout<<"Yes"<<endl;
return 0;
}
这道题还是比较简单的,但是图论的思想在各个领域里面都能用到。竞赛方面无论是数学建模还是物流管理,智能车还是无人驾驶,都非常重要。拓扑排序的思想也能在其中体现。
校学生会部长团答辩也答完了,近期有要开始补题了…11月还有7天,哎,还有两篇项目策划书,高数国赛,知识竞赛省赛…