WA,给的那个测试用例可以通过(因为给的用例就是简单的三个点,头到尾,最短路径等于最小生成树)
#include<bits/stdc++.h>
using namespace std;
/*
求把点连起来的最小路径,kruskal?dijkstra?
*/
int main(){
//kruskal用到并查集
//dijkstra不用
int n;
while(cin>>n)
{
vector<vector<float>>dist(n,vector<float>(n,0));//存放点i到j的距离
vector<vector<float>>pos(n,vector<float>(2,0));//存放点的坐标
for(int i=0;i<n;i++)
{
for(int j=0;j<2;j++)
{
cin>>pos[i][j];
}
}
for(int i=0;i<n;i++)//初始化dist矩阵,i到j的距离
{
for(int j=0;j<n;j++)
{
if(i==j){continue;}
int dx=pos[i][0]-pos[j][0];
int dy=pos[i][1]-pos[j][1];
dist[i][j]=sqrt(dx*dx+dy*dy);
}
}
//cout<<setprecision(3)<<dist[1][0];
//初始化dis数组,第一个dis数组以0号坐标点开始
float ans=0;
vector<int>visted(n,0);
visted[0]=1;
vector<float>dis(n,0);
int tmppos;
vector<int>load(n,0);
for(int i=1;i<n;i++)
{
dis[i]=dist[0][i];
}
for(int t=1;t<n;t++)//循环n
{ int mindis=INT_MAX;
for(int i=1;i<n;i++)
{
//找到dis中最近的
if(visted[i]!=1&&dis[i]<mindis)
{
mindis=dis[i];
tmppos=i;
}
}
visted[tmppos]=1;
//cout<<dis[tmppos];
//ans+=dis[tmppos];
load[t]=tmppos;
//找到最近的下一个点tmppos,从这里更新dis
for(int i=1;i<n;i++)
{
if(visted[i]!=1&&dis[tmppos]+dist[tmppos][i]<dis[i])//经过tmppos这个点的中转,更新dis数组
{//如果经中转后更近,那么更新dis
dis[i]=dis[tmppos]+dist[tmppos][i];
}
}
}
//for_each(load.begin(),load.end(),[](int val){cout<<val<<" ";});
for(int i=1;i<n;i++)
{
ans+=dist[i][i-1];
}
cout<<setprecision(3)<<ans<<endl;
}
return 0;
}
上面的dijkstra行不通,两个点间存在最短路径并不代表最后的生成树最小
换prim
load表示已经选取的节点
#include<bits/stdc++.h>
using namespace std;
/*
求把点连起来的最小路径,kruskal?dijkstra?
*/
int main(){
//kruskal用到并查集
//dijkstra不用
int n;
while(cin>>n)
{
vector<vector<double>>dist(n,vector<double>(n,0));//存放点i到j的距离
vector<vector<double>>pos(n,vector<double>(2,0));//存放点的坐标
for(int i=0;i<n;i++)
{
for(int j=0;j<2;j++)
{
cin>>pos[i][j];
}
}
for(int i=0;i<n;i++)//初始化dist矩阵,i到j的距离
{
for(int j=0;j<n;j++)
{
if(i==j){continue;}
int dx=pos[i][0]-pos[j][0];
int dy=pos[i][1]-pos[j][1];
dist[i][j]=sqrt(dx*dx+dy*dy);
}
}
//cout<<setprecision(3)<<dist[1][0];
//初始化dis数组,第一个dis数组以0号坐标点开始
double ans=0;
vector<int>visted(n,0);
visted[0]=1;
vector<double>dis(n,0);
int tmppos;
vector<int>load(n,0);
int k;
for(int i=1;i<n;i++)
{
dis[i]=dist[0][i];
}
for(int t=1;t<n;t++)//dijkstraWA了,换prim
{
double mindis=INT_MAX;
//min_edge=Max;
for(int i=0;i<t;i++)//在所有已选取的点中
{
for(int j=0;j<n;j++)//找距离最小且未访问过的边
{
if(dist[load[i]][j]<mindis&&visted[j]!=1)
{
mindis=dist[load[i]][j];
k=j;
}
}
}//寻找最小生成树中节点到其它节点最小的边。
load[t]=k;//将该节点加入到最小生成树节点集合
visted[k]=true;
//cout<<mindis<<" ";
ans=ans+mindis;//将该边的长度加入到sum中
}
cout<<setprecision(6)<<ans<<endl;
//cout<<dist[0][1];
}
return 0;
}