HDU-3371 Connect the Cities

来源:互联网 发布:windows模拟器 编辑:程序博客网 时间:2024/06/08 04:38

题目链接:https://vjudge.net/problem/HDU-3371

最小生成树的题,用kruskal算法+并查集做

这道题卡时比较严重,后面又用prim算法写了一遍,两种都是卡着过的

kruskal:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<set>#include<queue>using namespace std;const int N=500+10;const int M=25000+10;struct edge{int a,b,c;bool operator < (const edge &u) const{return c<u.c;}}e[M];int uf[N];int n,m,k,num,ans;void init(){num=n-1;for(int i=1;i<=n;i++)uf[i]=i;ans=0;}int f(int u){if(uf[u]!=u)uf[u]=f(uf[u]);return uf[u];}void kruskal(){int r1,r2;for(int i=0;i<m;i++){if(!num) break;r1=f(e[i].a);r2=f(e[i].b);if(r1!=r2){uf[r2]=r1;ans+=e[i].c;num--;}}}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d%d",&n,&m,&k);init();for(int i=0;i<m;i++)scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);int p,q,c;int r1,r2;for(int i=0;i<k;i++){scanf("%d%d",&c,&p);r1=f(p);while(--c){scanf("%d",&q);r2=f(q);if(r1!=r2){uf[r2]=r1;num--;}}}sort(e,e+m);kruskal();if(!num) printf("%d\n",ans);else printf("-1\n");}return 0;}

prim:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int N=500+10;const int MC=1000000;int g[N][N];int n,m,k;void init(){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)g[i][j]=MC;}int prim(){int min,minid,sum=0;int lowcost[N];for(int i=2;i<=n;i++)lowcost[i]=g[1][i];for(int i=2;i<=n;i++){min=MC;minid=0;for(int j=2;j<=n;j++){if(lowcost[j]<min&&lowcost[j]!=-1){min=lowcost[j];minid=j;}}if(min>1000) return -1;sum+=min;lowcost[minid]=-1;for(int j=2;j<=n;j++)if(g[minid][j]<lowcost[j])lowcost[j]=g[minid][j];}return sum;}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d%d",&n,&m,&k);init();int a,b,c;for(int i=0;i<m;i++){scanf("%d%d%d",&a,&b,&c);if(c<g[a][b])g[a][b]=g[b][a]=c;}for(int i=0;i<k;i++){scanf("%d%d",&c,&a);while(--c){scanf("%d",&b);g[a][b]=g[b][a]=0;a=b;}}int ans=prim();printf("%d\n",ans);}return 0;}


原创粉丝点击