list<side>createMST(){ list<side> result; int index =0; for(int i =1; i != n;){ int head =find(sideMap[index].head); int tail =find(sideMap[index].tail); if(head != tail){ result.push_back(sideMap[index]); merge(head, tail); ++i; } ++index; } return result; }
运行过程
点击查看运行过程(图片较多)
黑色线:还未遍历
红色线:丢弃的线
紫色线:采用的线
注:为了作图方便,对于权重一样的线,按随机顺序选用
这个样例没选好,导致前面N - 1条线全部都选用了,下次我注意
Prim
Prim算法以点为基础构建树:
以任意一个点开始生成
计算其它点(即不在树中的点)距离树的距离
选择距离最短的点加入树中
重复2直到连接了所有的点
存储点信息
在Prim算法中一个点有以下信息需要存储:
是否已经在树中
它连接了哪些点
对于第一个非常好处理,直接使用bool数组、set或者map就可以了。
至于一个点连接了哪些点的存储方式,我们也不多说了,可以参考图的存储。
存储边信息
上面已经说过了,这里就不重复了。
点边合并存储
采用Prim算法时,很多情况下我们可以合并点和边的信息,我们可以使用下面的这个结构体:
1 2 3 4 5 6
structpoint{ //连接的点编号 int index; //两点距离(或者说是两点连线的权重) int value; }
longlongsolve(){ longlong result =0; auto it = sideMap.begin(); for(int i =1; i != n;){ auto& node =*it; int head =find(node.head); int tail =find(node.tail); if(head != tail){ merge(head, tail); result += node.value; ++i; } ++it; } return result; }
intmain(){ int m, a, b, value; cin >> n >> m; for(int i =1; i <= n;++i) pointMap[i]= i; while(m--){ scanf("%d %d %d",&a,&b,&value); sideMap.emplace(a, b, value); } cout <<solve(); return0; }
int jumpDis[500]; pair<int,int> treeMap[1000];// NOLINT(cert-err58-cpp)
intdistance(int a,int b){ int difX = treeMap[a].first - treeMap[b].first; int difY = treeMap[a].second - treeMap[b].second; double dis =sqrt(difX * difX + difY * difY); int result =int(dis)<<1; if(dis -int(dis)>1e-6)++result; return result; }
intsolve(int n){ typedef pair<int,int> info; bool check[1000]{true,}; priority_queue<info, vector<info>, greater<info>> near; int last =0; int result =0; for(int i =1; i != n;++i){ for(int k =1; k != n;++k){ if(!check[k]) near.emplace(distance(last, k), k); } while(!near.empty()){ auto node = near.top(); near.pop(); if(check[node.second])continue; check[node.second]=true; result =max(result, node.first); last = node.second; break; } } return result; }
intmain(){ int m, n; cin >> m; for(int i =0; i != m;++i){ scanf("%d",&jumpDis[i]); jumpDis[i]<<=1; } sort(jumpDis, jumpDis + m); cin >> n; for(int i =0; i != n;++i){ scanf("%d %d",&treeMap[i].first,&treeMap[i].second); } int maxDis =solve(n); int result; if(maxDis > jumpDis[m -1]) result =0; else{ int index =int(upper_bound(jumpDis, jumpDis + m, maxDis)- jumpDis); if(index == m) result = m; elseif(jumpDis[index -1]== maxDis) result = m - index +1; else result = m - index; } cout << result; return0; }