hdu 3371 最小生成树(有重边)

G++提交又超市了,囧

c++就AC了

开始没有判重,错了几遍

最小生成树简dan题

prim和克鲁斯卡尔

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,k,p[505],ans;
struct node{
int u,v,w;
}pt[250000];
int cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int i,j,num,a,b,root,x,y;
for(i=0;i<=500;i++) p[i]=i;
bool flag=false;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=m;i++)scanf("%d%d%d",&pt[i].u,&pt[i].v,&pt[i].w);
sort(pt+1,pt+m+1,cmp);
for(i=1;i<=k;i++)
{
scanf("%d%d",&num,&root);
for(j=1;j<num;j++)
{
scanf("%d",&a);
x=find(a),y=find(root);
if(x!=y) p[x]=y;
}
}
for(num=0,i=1;i<=n;i++) if(p[i]==i) num++;
for(ans=0,i=1;i<=m;i++)
{
x=find(pt[i].u);y=find(pt[i].v);
if(x!=y)
{
p[x]=y;
ans+=pt[i].w;num--;
}
if(num==1)
{
flag=true;
break;
}
}
if(flag) printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}



View Code
#include<stdio.h>
#include<string.h>
#define inf 99999999
int flag[500];
int D[500];
int map[505][505];
int n,i,j;
int prime()//下标1开始
{
int v,k;
int ret=0,mi;
for(i=1;i<=n;i++){
flag[i]=0;
D[i]=inf;
}D[1]=0;flag[1]=1;v=1;
for(k=1;k<n;k++){
for(i=1;i<=n;i++)if(!flag[i]){
if(map[v][i]<D[i])
D[i]=map[v][i];
}
mi=inf;
for(i=1;i<=n;i++)
if(!flag[i]&&D[i]<mi)
mi=D[v=i];
flag[v]=1;
ret+=mi;
}
return ret;
}
int num[505];
int main()
{
int t,m,k,x,i,j;
scanf("%d",&t);
while(t--)
{
int a,b,w;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;i++)
{
map[i][i]=0;
for(j=i+1;j<=n;j++)
map[i][j]=map[j][i]=inf;
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&w);
if(w<map[a][b])
map[a][b]=map[b][a]=w;
}
for(i=0;i<k;i++)
{
scanf("%d",&m);
for(j=0;j<m;j++)
scanf("%d",&num[j]);
for(j=0;j<m;j++)
for(x=j+1;x<m;x++)
map[num[j]][num[x]]=map[num[x]][num[j]]=0;
}
int ans=prime();
if(ans>=inf)
printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}



 

你可能感兴趣的:(最小生成树)