最小生成树+并查集模板
hdu 1233:
hdu 1102:
poj 1789:
hdu 1301:
hdu 2682
模板:
#include<stdio.h>#include<string.h>
#include<stdlib.h>
#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
int a[601][601];
int dis[601],vis[601],n,m,k;
int f[601];
int find(int t)//并查集判断是否连通
{
if(f[t]==-1) return t;
return f[t]=find(f[t]);
}
void bing(int a,int b)
{
int t1=find(a);
int t2=find(b);
if(t1!=t2) f[t1]=t2;
}
int prim()//普里姆算法
{
int sum=0,i,j,k=0,minn;
memset(vis,0,sizeof(vis));
for(i=0; i<n; i++)
{
dis[i]=a[0][i];
vis[i]=0;
}
vis[0]=1;
for(i=0; i<n-1; i++)
{
minn=inf;
for(j=0; j<n; j++)
{
if(vis[j]==0&&dis[j]<minn)
{
minn=dis[j];
k=j;
}
}
sum+=minn;
vis[k]=1;
for(j=0; j<n; j++)
{
if(vis[j]==0&&dis[j]>a[k][j]) dis[j]=a[k][j];
}
}
return sum;
}
int main()
{
while(scanf("%d%d",&m,&n),m!=0)
{
int i,x,y,d;
memset(a,inf,sizeof(a));
for(i=0; i<n; i++)
a[i][i]=0;
for(i=1;i<=n;i++)
f[i]=-1;
for(i=0; i<m; i++)
{
scanf("%d%d%d",&x,&y,&d);
bing(x,y);
a[x-1][y-1]=a[y-1][x-1]=d;
}
int res=0;
for(i=1;i<=n;i++)
{
if(f[i]==-1) res++;
}
//printf("%d\n",res);//只能
if(prim()==0||prim()==inf||res>1)
printf("?\n");
else
printf("%d\n",prim());
}
}