杭电 3371 kruskal()算法

话说这道蛋疼的题,是专题里面的,我现在还是没有过,,,,,,TLE到吐血,,TLE了20多次,,,还是过不了。G++真让人蛋疼,,,在外面用C++,600ms过了。蛋疼,,,,,,,听说用prime900多ms可以过,,囧,,,明天看看prime算法,,再试试。。。。。题目:

Connect the Cities

Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2756Accepted Submission(s): 844


Problem Description
In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities again, but they don’t want to take too much money.

Input
The first line contains the number of test cases.
Each test case starts with three integers: n, m and k. n (3 <= n <=500) stands for the number of survived cities, m (0 <= m <= 25000) stands for the number of roads you can choose to connect the cities and k (0 <= k <= 100) stands for the number of still connected cities.
To make it easy, the cities are signed from 1 to n.
Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.
Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.

Output
For each case, output the least money you need to take, if it’s impossible, just output -1.

Sample Input
 
 
1 6 4 3 1 4 2 2 6 1 2 3 5 3 4 33 2 1 2 2 1 3 3 4 5 6

Sample Output
 
 
1
#include <iostream> #include <string.h> #include <algorithm> using namespace std; const int N=25010; int leftt[N],rightt[N],value[N],r[N],father[N]; int cmp(int i,int j){ return value[i]<value[j]; } int find(int x){ if(father[x]!=x) father[x]=find(father[x]); return father[x]; } int main(){ int kk; scanf("%d",&kk); while(kk--){ for(int i=0;i<N;++i){ leftt[i]=0;rightt[i]=0; value[i]=1000005; r[i]=i; father[i]=i; } int n,m,k; scanf("%d%d%d",&n,&m,&k); int a,b,c,i,j,num=0; for(i=0;i<m;++i){ scanf("%d%d%d",&leftt[i],&rightt[i],&value[i]); } int t,x,y; while(k--){ scanf("%d",&t); scanf("%d",&x); t--; while(t--){ scanf("%d",&y); leftt[m]=x; rightt[m]=y; father[m]=x; value[m]=0; m++; } } /*for(i=0;i<m;++i) printf("%d ",father[i]); printf("\n");*/ sort(r,r+m,cmp); int sum=0; for(i=0;i<m;++i){ int pos=r[i]; /*printf("%d\n",pos);*/ int xx=find(leftt[pos]); int yy=find(rightt[pos]); /*printf("xx=%d yy=%d\n",xx,yy);*/ if(xx!=yy){ father[yy]=xx; sum+=value[pos]; /* printf("sum=%d\n",sum);*/ } } int flag=1; int zz=find(father[1]); for(i=2;i<=n;++i){ if(zz!=father[i]&&zz!=find(father[i])) {flag=0;break;} } if(flag) printf("%d\n",sum); else printf("-1\n"); } return 0; }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Prim算法Kruskal算法都是求解最小生成树的经典算法,但它们的实现方式和思路有所不同。 Prim算法是一种贪心算法,它从一个起点开始,每次选择与当前生成树距离最近的一个点加入生成树,直到所有点都被加入生成树为止。Prim算法的时间复杂度为O(n^2),其中n为节点数。 Kruskal算法也是一种贪心算法,它从所有边中选择权值最小的边加入生成树,直到生成树中包含所有节点为止。Kruskal算法的时间复杂度为O(mlogm),其中m为边数。 因此,Prim算法适用于稠密图,而Kruskal算法适用于稀疏图。同时,Prim算法的实现方式比Kruskal算法更简单,但Kruskal算法的时间复杂度更优秀。 ### 回答2: prim算法kruskal算法都是解决最小生成树问题的经典算法,但是它们的具体实现方式以及解决问题的思路有所不同。 首先,prim算法是一种贪心算法,它的基本思想是从一个顶点开始,以该顶点为起点,不断选择与当前生成树相邻的最小权值的边所连接的顶点加入生成树中,直到生成树覆盖所有的顶点为止。prim算法中需要使用一个数组来记录已经加入生成树的顶点,以及一个数组来记录每个顶点与生成树之间的最小距离,这些数组的更新和维护需要从当前顶点出发,枚举所有相邻的边,找到最小的那条边,更新记录的信息。 与之不同的是,kruskal算法也是一种贪心算法,但它的实现方式更为简单。kruskal算法首先将图中的所有边按照权值从小到大排序,然后从权值最小的边开始,一条一条地将边加入生成树中,如果加入某条边之后形成的图不是生成树,则舍弃这条边并考虑下一条权值更大的边,直到生成树覆盖所有的顶点为止。kruskal算法实现的关键是使用并查集来判断当前要加入的边是否会构成环路,进而确定该边是否应该加入生成树中。 两种算法的时间复杂度都是O(E log E),其中E为边的数量,总体上来说prim算法的实现相对较为复杂,但它在密集图中的表现更好;而kruskal算法更简单,适用于稀疏图。此外,由于prim算法的实现涉及到了不同的数据结构操作,其空间复杂度也相对较高,而kruskal算法则只需要一个并查集数据结构即可。 总之,prim算法kruskal算法是解决最小生成树问题的两种重要算法,其中prim算法需要借助一个单源最短路径算法来实现,并涉及到更加复杂的数据结构操作,而kruskal算法则相对更为简单直观,适合处理稀疏图。 ### 回答3: prim算法kruskal算法是解决最小生成树问题(Minimum Spanning Tree)的两种经典算法。 1. 基本思路不同 Prim算法是一种贪心算法,从一个源点开始构造生成树,每次将新加入一个顶点的边的权值最小的边加入生成树中,直到所有的顶点都加入了生成树,生成树的总权值则是所有加入的边的权值之和。 Kruskal算法则不需要从一个源点开始构造生成树,而是将所有边按照权值从小到大排序,然后顺序加入生成树,当加入的边会和生成树中已有的边形成环时,该边就被舍弃,直到所有顶点都在生成树中。 2. 运行时间不同 Prim算法的时间复杂度为O(n^2)或者O(nlogn),其中n是图中节点的数量,如果使用堆等数据结构,则时间复杂度可以降至O(mlogn),其中m是图中边的数量,因此 Prim 算法适用于稠密图。 Kruskal算法的时间复杂度为O(mlogm),其中m是图中边的数量,因此 Kruskal 算法适用于稀疏的图。 3. 使用场景不同 Prim算法可以使用在连通图中寻找最小生成树,但是如果该图不连通,则需要对每个连通子图都执行一遍 Prim 算法,得到的最小生成树将合并。 Kruskal算法同样可以在连通图中寻找最小生成树,也可以应用在拓扑排序中,以及一些网络设计,电路设计等方面。 总的来说, Prim 算法Kruskal 算法虽然都是解决最小生成树问题的经典算法,但是在实际应用中会根据不同的场景和要求选择使用相应的算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值