社区讨论

Prim+优先队列 求查错

P1265公路修建参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi6yl9fm
此快照首次捕获于
2025/11/20 12:56
4 个月前
此快照最后确认于
2025/11/20 12:56
4 个月前
查看原帖
CPP
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>

using namespace std;
const int maxn = 5000 + 10;
int n;
double ans;

struct edge
{
	int u , v;
	double w;
	edge(int _u, int _v, double _w): u(_u) , v(_v) ,w(_w){} //注意w别开整形了 
	edge() {}
	
	bool operator < (const edge& b) const{	return w > b.w;	} //这里少了const优先队列报错 
};

//struct cmp{	bool operator () (edge& a,edge& b)	{ return a.w < b.w;}};
//SORT默认小到大,重载小于为真小于  优先队列是反着的,包括排序函数 
priority_queue<edge> e;

struct point
{
	double x , y;
	bool vis;
}d[maxn];

double dis(point& a,point& b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

void pushe(int f)
{
	for(int i=1; i<=n; i++)
		if(!d[i].vis) 
		{
			e.push(edge(f,i,dis(d[i],d[f])));
			printf("ADD (%f,%f) to (%f,%f) and W=%f\n",d[f].x,d[f].y,d[i].x,d[i].y,dis(d[i],d[f]));
		}
}

int main()
{
	cin >> n;
	for(int i=1; i<=n; i++)
		cin >> d[i].x >> d[i].y;
	
	d[1].vis = 1;
	pushe(1);
	
	for(int i=1; i<n; i++)
	{
		while(d[e.top().v].vis)
		{
			printf("DEL (%f,%f) to (%f,%f)\n",d[e.top().u].x,d[e.top().u].y,d[e.top().v].x,d[e.top().v].y);
			e.pop();
		}

		printf("SEL (%f,%f) to (%f,%f)\n",d[e.top().u].x,d[e.top().u].y,d[e.top().v].x,d[e.top().v].y);
		
		int j = e.top().v;  //u是从 v是到 
		ans += e.top().w;
		d[j].vis = 1;
		pushe(j);
		e.pop();
	
	}
	
	while(!e.empty())
	{
		printf("(%f,%f) to (%f,%f)\n",d[e.top().u].x,d[e.top().u].y,d[e.top().v].x,d[e.top().v].y);
		e.pop();
	}
	
	printf("%.2f",ans);
	return 0;
}

运行结果
CPP
4
0 0
1 2
-1 2
0 4
ADD (0.000000,0.000000) to (1.000000,2.000000) and W=2.236068
ADD (0.000000,0.000000) to (-1.000000,2.000000) and W=2.236068
ADD (0.000000,0.000000) to (0.000000,4.000000) and W=4.000000
SEL (0.000000,0.000000) to (1.000000,2.000000)
ADD (1.000000,2.000000) to (-1.000000,2.000000) and W=2.000000
ADD (1.000000,2.000000) to (0.000000,4.000000) and W=2.236068
DEL (0.000000,0.000000) to (1.000000,2.000000)
SEL (0.000000,0.000000) to (-1.000000,2.000000)
ADD (-1.000000,2.000000) to (0.000000,4.000000) and W=2.236068
SEL (1.000000,2.000000) to (0.000000,4.000000)
(-1.000000,2.000000) to (0.000000,4.000000)
(0.000000,0.000000) to (0.000000,4.000000)
6.71
--------------------------------
(原题有样例的图) 应该选中 ADD (1.000000,2.000000) to (-1.000000,2.000000) and W=2.000000这个边呀,可是输出后删除、剩余、选中这条边都没这条边

回复

2 条回复,欢迎继续交流。

正在加载回复...