這道題目,其實和以前做過的還是有那麼點類似的,主要就是你把已經建成的先賦成0,因為人家已經建成了,你怎麼能讓人家繼續掏錢呢?
本來想用並查集去判斷是不是通路的,在想一想,其實不用那麼複雜,你首先把dis[i]都賦成了最大值inf,那也就是如果沒有聯通的話,這個邊是不會更新的 所以在最後面加一個判斷是不是有inf的邊沒有更新就可以判斷出到底是不是通路了,
貼出代碼:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#define inf 0x3fffffffint N,M;//N stands for the number of points,and M represents the number of edges;int alM;//alM stands for the number of that has already builded cities;int dis[510];int visit[510];int map[510][510];void prim(){for(int i=1;i<=N;i++){dis[i]=inf;}dis[1]=0;for(int j=1;j<=N;j++){int t=inf,pos;for(i=1;i<=N;i++){if(!visit[i]&&t>dis[i]){t=dis[i];pos=i;}}visit[pos]=1;for(i=1;i<=N;i++){if(!visit[i]&&dis[i]>map[pos][i]&&map[pos][i]!=0x3f3f3f3f){dis[i]=map[pos][i];}}}int temp=0;int flag=1;for(i=1;i<=N;i++){if(dis[i]==inf)flag=0;temp+=dis[i];}if(flag==1)printf("%d\n",temp);elseprintf("-1\n");}int main(){int T;int x[105];scanf("%d",&T);while(T--){memset(visit,0,sizeof(visit));memset(map,0x3f,sizeof(map));scanf("%d%d%d",&N,&M,&alM);int a,b,val;for(int i=1;i<=M;i++){scanf("%d%d%d",&a,&b,&val);if(val<map[a][b]){map[a][b]=val;map[b][a]=val;}}for(int j=1;j<=alM;j++){int t;int kk;scanf("%d",&t);for(kk=1;kk<=t;kk++){scanf("%d",&x[kk]);}for(i=1;i<t;i++){for(int k=i+1;k<=t;k++){map[x[i]][x[k]]=0;map[x[k]][x[i]]=0;}}}prim();}return 0;}