求最小生成树
给定k个联通的块,对于第i个联通块,有ci个城市互相联通,这里只要把块中的每个城市跟其他任意一个相连就可以,即设2个城市之间的边权值为0
注意判重边
C++AC,G++TLE
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#define N 25000+5
#define INF 1<<30
using namespace std;
int map[505][505],vis[505],closed[505];
int m,n,k;
void prime(){
int i,j,Min,mark,ans=0;
for(i=1;i<=n;i++){
closed[i]=map[i][1];
vis[i]=0;
}
vis[1]=1;
for(i=1;i<n;i++){
Min=INF;
for(j=1;j<=n;j++){
if(!vis[j]&&closed[j]<Min){
Min=closed[j];
mark=j;
}
}
if(Min==INF){
break;
}
vis[mark]=1;
ans+=Min;
for(j=1;j<=n;j++){
if(map[mark][j]<closed[j])
closed[j]=map[mark][j];
}
}
if(i==n)
printf("%d\n",ans);
else
printf("-1\n");
}
int main()
{
int t,tmp,i,j,v,u;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
map[i][j]=INF;
}
}
for(i=0;i<m;i++){
scanf("%d%d",&u,&v);
scanf("%d",&tmp);
map[u][v]=min(tmp,map[u][v]);
map[v][u]=min(tmp,map[v][u]);
}
memset(vis,0,sizeof(vis));
while(k--){
scanf("%d%d",&tmp,&u);
tmp--;
while(tmp--){
scanf("%d",&v);
map[u][v]=map[v][u]=0;
u=v;
}
}
/* for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
cout<<map[i][j]<<' ';
}
cout<<endl;
}*/
prime();
}
return 0;
}