//我的prim算法
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #define MAX 0x0fffffff using namespace std; int map[501][501],minnum[501]; int prim(int n) { int sum=0,i,j; for(i=1;i<=n;i++) { minnum[i]=map[1][i]; } minnum[1]=0; for(i=1;i<n;i++) { int min=MAX,k; for(j=2;j<=n;j++) { if(minnum[j]!=0&&minnum[j]<min) { min=minnum[j]; k=j; } } sum+=min; minnum[k]=0; for(j=2;j<=n;j++) { minnum[j]=minnum[k]+map[k][j]<minnum[j]?minnum[k]+map[k][j]:minnum[j]; } } return sum; } int main() { int n,v,e,a,b,c; scanf("%d",&n); while(n--) { memset(map,127,sizeof(map)); scanf("%d%d",&v,&e); while(e--) { scanf("%d%d%d",&a,&b,&c); map[a][b]=c; map[b][a]=c; } int min=MAX; for(int i=0;i<v;i++) { scanf("%d",&a); min=min>a?a:min; } printf("%d ",min+prim(v)); } return 0; }
//prim算法解决 图论同学的代码 #include <iostream> #include <cstdio> #include <string.h> using namespace std; #define MAX 0x0ffffff int map[510][510],lowcost[510]; int N,sum; int min(int x,int y){return x<y?x:y;} void prim() { sum=0; for(int i=1;i<=N;i++) //初始化 lowcost[i]=map[1][i]; lowcost[1]=0; //等于零表示在最小路径集合中 for(int i=2;i<=N;i++) { int k,minn=MAX; for(int j=2;j<=N;j++) //找最小边 { if(lowcost[j]<minn&&lowcost[j]!=0) { minn=lowcost[j]; k=j; } } sum+=minn; lowcost[k]=0; for(int j=2;j<=N;j++) if(map[k][j]<lowcost[j]) lowcost[j]=map[k][j]; } } int main() { int T,m,minn; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&m); for(int i=0;i<=N;i++) for(int j=0;j<=N;j++) map[i][j]=MAX; while(m--) { int x,y,len; scanf("%d%d%d",&x,&y,&len); map[x][y]=map[y][x]=len; } minn=MAX; for(int i=1;i<=N;i++) { scanf("%d",&m); minn=min(minn,m); } prim(); printf("%d ",sum+minn); } return 0; }
//自己写的kruskal算法
#include<stdio.h>
#include<string.h> #include<algorithm> #include<math.h> using namespace std; struct build { int b,e,num; }bu[125000]; bool cmp(build a,build b) { return a.num<b.num; } int p[510]; int find(int n) { return p[n]==n?n:p[n]=find(p[n]); } int kruskal(int m) { int sum=0,i; for(i=0;i<510;i++) p[i]=i; sort(bu,bu+m,cmp); for(i=0;i<m;i++) { int x,y; x=find(bu[i].b);y=find(bu[i].e); if(x!=y) { sum+=bu[i].num; p[x]=y; } } return sum; } int main() { int n,v,e,i,a; scanf("%d",&n); while(n--) { scanf("%d%d",&v,&e); for(i=0;i<e;i++) scanf("%d%d%d",&bu[i].b,&bu[i].e,&bu[i].num); int min=7634634; for(i=0;i<v;i++) { scanf("%d",&a); if(a<min) min=a; } printf("%d ",min+kruskal(e)); } return 0; }
//用我自己的方法进行了优化
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
struct build
{
int b,e,num;
}bu[125000];
bool cmp(build a,build b)
{return a.num<b.num;}
int p[501];
int find(int n)
{return p[n]==n?n:p[n]=find(p[n]);}
int kruskal(int n,int m)
{
int sum=0,i,flag=0;
for(i=0;i<510;i++)
p[i]=i;
sort(bu,bu+m,cmp);
for(i=0;i<m;i++)
{
int x,y; x=find(bu[i].b);y=find(bu[i].e);
if(x!=y)
{
sum+=bu[i].num;
flag++;
p[x]=y;
}
if(flag==n-1)
break;
}
return sum;
}
int main()
{
int n,v,e,i,a;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&v,&e);
for(i=0;i<e;i++)
scanf("%d%d%d",&bu[i].b,&bu[i].e,&bu[i].num);
int min=7634634;
for(i=0;i<v;i++)
{
scanf("%d",&a);
if(a<min)
min=a;
}
printf("%d
",min+kruskal(v,e));
}
return 0;
}