每一个结点一个数组,所有结点又构成一个数组,即二维。
结点的数组保存的是与这个结点相邻的所有点的编号。
vector<int>G[maxn]; //(maxn为点的总个数)
void read_tree()
{
int u,v;
scanf("%d",&n);
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&u,&v);//(u与v之间有边)
G[u].push_back(u);
G[v].push_back(v);
}
}
把上面的矩阵关系转化为一颗树(主要增加谁是根的问题)
void dfs(int u,int fa)
{
int d=G[u].size();
for(int i=0;i<d;i++)
{
int v=G[u][i];
if(v!=fa)
dfs(v,p[v]=u);
}
}
p[i]=i的父结点的编号;
调用:dfs(root,-1);
kruskal,并查集,复杂度为。。。o(1)?
int cmp(const int i,const int j)
{
return w[i]<w[j];
}
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
int kruskal()
{
int ans=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
sort(r,r+m,cmp);
for(int i=0;i<m;i++)
{
int e=r[i];
int x=find(u[e]);
int y=find(v[e]);
if(x!=y)
{
ans+=w[e];
p[x]=y;
}
}
return ans;
}
如果需要的功能不仅仅是检测两个节点是否连通,还需要在连通时得到具体的路径,那么就需要用到别的算法了,比如DFS或者BFS。
时间复杂度
并查集:原图有n个点,则并查集的初始图是n个度为0的点,然后用原图的边权排序遍历,构造一棵新的树,从而得到我们想要的ans
但此时无法得到具体路径,因为需要用dfs或bfs才能得到。