思路:
你到底懂不懂最小生成树算法,两点距离到底为多少?为d[i][j]+c[i]+c[j],一定要先加上再用模板啊!
代码:
// Prim算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int Max_n=1100;
int T,n;
int d[Max_n][Max_n];
int c[Max_n];
bool used[Max_n];
int dist[Max_n];
int Prim(){
memset(used,0,sizeof(used));
memset(dist,0x3f,sizeof(dist));
dist[1]=0;
int ans=0;
while(true){
int u=-1;
for(int i=1;i<=n;i++){
if(!used[i]&&(u==-1||dist[i]<dist[u]))
u=i;
}
if(u==-1)break;
used[u]=1;
ans+=dist[u];
for(int i=1;i<=n;i++){
if(!used[i]&&dist[i]>d[u][i])
dist[i]=d[u][i];
}
}
return ans;
}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&d[i][j]);
d[i][j]+=c[i]+c[j];
}
}
printf("%d\n",Prim());
}
return 0;
}
//Kruskal算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int Max_n=1100;
int T,n;
int d[Max_n][Max_n];
int c[Max_n];
struct edge{
int from,to,cost;
bool operator<(const edge& e)const{
return cost<e.cost;
}
}es[Max_n*Max_n];
int par[Max_n];
int Find(int x){
if(par[x]==x)return x;
return par[x]=Find(par[x]);
}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
par[i]=i;
scanf("%d",&c[i]);
}
int k=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&d[i][j]);
d[i][j]+=c[i]+c[j];
if(i<j){
es[k].from=i;es[k].to=j;
es[k++].cost=d[i][j];
}
}
}
sort(es,es+k);
int ans=0;
for(int i=0;i<k;i++){
int fx=Find(es[i].from);
int fy=Find(es[i].to);
if(fx!=fy){
ans=ans+es[i].cost;
par[fx]=fy;
}
}
printf("%d\n",ans);
}
return 0;
}