边数和顶点个数上限分别为M和N,注意开辟的数组里面有的大小是M,有的大小是N
#define M 200000
#define N 100000
结构体: 边edge、顶点node(node用于并查集) 全局数组:边集e,大小是边数上限、点集v,大小是顶点数上限 并查集中,顶点的root为true时该顶点是根节点;当顶点是根节点时,parent等于整棵树的元素个数,否则是该顶点的父节点序号值;初始化的点集中,每个顶点都是单独的一个根节点
struct edge
{
int x, y, w;
bool operator < ( edge e)
{
return w < e. w;
}
} ;
edge e[ M + 5 ] ;
struct node
{
int parent;
bool root;
node ( )
{
parent = 1 ;
root = true;
}
} ;
node v[ N + 5 ] ;
并查集操作:查找根节点 find 和合并 unite 合并时,要将元素少的树并到元素多的树上,如果是随便合并,则数据多的时候可能会超时
int find ( int a)
{
while ( v[ a] . root != true)
a = v[ a] . parent;
return a;
}
void unite ( int a, int b)
{
if ( v[ a] . parent > v[ b] . parent)
{
v[ b] . root = false;
v[ a] . parent + = v[ b] . parent;
v[ b] . parent = a;
}
else
{
v[ a] . root = false;
v[ b] . parent + = v[ a] . parent;
v[ a] . parent = b;
}
}
int main ( )
{
int n, m;
sort ( e, e + m) ;
int cnt = 0 ;
for ( int i = 0 ; i < m; ++ i)
{
int u = find ( e[ i] . x) ;
int v = find ( e[ i] . y) ;
if ( u != v)
{
++ cnt;
unite ( u, v) ;
if ( cnt == n - 1 ) break ;
}
}
if ( cnt < n - 1 ) ;
else ;
return 0 ;
}
求从a到b的一条路径,使得路径上最大边的权值最小 可以进行最小生成树计算,每次加入一条边之后判断ab是否连通 find(a) == find(b) 如果连通,刚才加的边就是满足条件的边