比较水的题目,裸prim....下面代码写得有点麻烦...仅供参考..(其实不用写那么多记录...我是蒟蒻...QAQ)
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<functional>
using namespace std;
//------------------------------------------
const int M=105;
const int INF=0xfffffff;
//-----------------------------------------
typedef pair<int,int >P;
priority_queue<P, vector<P>, greater<P> > que;//单调队列优化prim
//------------------------------------------
struct node
{
int x, y;
};
node ans[M];
int map[M][M];
int n;
int sum=0;
int cost[M];
int vis[M];
int re[M];//记录连线的点的顺序
int point[M];//记录连松弛改点的点
//-----------------------------------------
bool cmp(node a, node b)
{
if (a.x==b.x) return a.y<b.y;
else return a.x<b.x;
}
void init()
{
memset(ans, 0, sizeof(ans));
memset(vis, 0, sizeof(vis));
scanf("%d", &n);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d", &map[i][j]);
for(int i=1; i<=n; i++) cost[i]=INF;
}
void solve()
{
memset(re, 0, sizeof(re));
memset(point, 0, sizeof(point));
int tott=0;
cost[1]=0;
que.push(P(0,1));
while (!que.empty())
{
P s=que.top();
que.pop();
int v=s.second;
if (cost[v] < s.first) continue;
sum+=s.first;
vis[v]=1;
re[++tott]=v;
for(int i=1; i<=n; i++)
{
if (!vis[i] && i!=v && map[v][i] < cost[i])
{
cost[i]=map[v][i];
point[i]=v;
que.push(P(cost[i],i));
}
}
}
node temp[M];
for(int i=2; i<=n; i++)
{
ans[i-1].x=point[re[i]];
ans[i-1].y=re[i];
}
int tot=0;
for(int i=1; i<n; i++) if (map[ans[i].x][ans[i].y]) {
if (ans[i].x > ans[i].y) {
int tt=ans[i].x;
ans[i].x=ans[i].y;
ans[i].y=tt;
}
temp[++tot].x=ans[i].x;
temp[tot].y=ans[i].y;
}
printf("%d\n", tot);
for(int i=1; i<=tot; i++)
{
printf("%d %d\n", temp[i].x, temp[i].y);
}
printf("%d\n",sum);
}
int main()
{
init();
solve();
return 0;
}
本文介绍了一个使用Prim算法解决最小生成树问题的C++实现。通过优先队列优化算法性能,详细展示了从初始化到求解整个过程的代码实现。
2337

被折叠的 条评论
为什么被折叠?



