hdu3371 Connect the Cities

来源:互联网 发布:游戏常用的算法 编辑:程序博客网 时间:2024/05/29 07:37

这题要注意的是,对已经存在的连通的边,直接合并,不要建边,这样可以省时间


#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;struct node{int u,v;int w;}e[50000];int n,m,father[50000];int cmp(node a,node b){return a.w<b.w;}int findroot(int p){if(father[p]!=p)father[p]=findroot(father[p]);return father[p];}void unionset(int p,int q){father[q]=p;}int kruskal(int k){int res=0;int j=0;while(k<n&&j<m){int m1=e[j].u,m2=e[j].v;int sn1=findroot(m1),sn2=findroot(m2);if(sn1!=sn2){res+=e[j].w;k++;unionset(sn1,sn2);}j++;}if(k!=n)res=-1;return res;}int main(){int t;scanf("%d",&t);while(t--){int k;scanf("%d%d%d",&n,&m,&k);int i,j;for(i=1;i<=n;i++)father[i]=i;for(i=0;i<m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);e[i].u=u;e[i].v=v;e[i].w=w;}int sum=1;   //代表已经建边的边数,用于判断是否能够联通 for(i=0;i<k;i++){int num;scanf("%d",&num);int x;scanf("%d",&x);x=findroot(x);for(j=1;j<num;j++){//如果已经连接,不要再次建边,会T,直接合并点就可以 int y;scanf("%d",&y);y=findroot(y);if(x!=y){unionset(x,y);sum++;}}}sort(e,e+m,cmp);int ans=kruskal(sum);printf("%d\n",ans);}return 0;}


原创粉丝点击