POJ1287-Networking
继续刷邝斌带你飞最小生成树专题
题意重点:
无向向图
如:1 2 3和2 1 3都表示一个含义,即1到2路径长度是3且2到1的路径也是3,这样说有点歧义,换个说法,点1和点2之间有个双向桥,这个情况的表述方法就是1 2 3或2 1 3
点数P
1~P,最大50,为0结束
边数R
貌似无穷多条,题目原文:The number of possible routes is unlimited.
线路最大长度100,即权值
两点之间可能有很多路
保证两点之间有连接就行。
普里姆、堆优化普里姆、克鲁斯卡尔都会了
就没必要再写了感觉
直接克鲁斯卡尔最优算法给他切了完事
不对,这题边无穷多个,点只有50,克鲁斯卡尔存图涉及边,普里姆堆优化也涉及边。直接邻接矩阵朴素普里姆开切
照着上一个博客里高深博客里的那个图,即这个

写的,还是略有些费劲的,但也不慢了20min,都没调试,直接一次AC,好爽,手感好棒
再次觉得邝斌题目层次性极强,上个题正好写完所有写法。尽管这个其实更简单但没法用边数的克鲁斯卡尔和堆优化普里姆,因为边数未知。且这个题正好适合自己过一遍普里姆算法。的确是大水题,不过并没有POJ评论区说的那么痛快的感觉,可能还是我学新东西比较适应慢吧,后期就行了,之前并查集我轻松AC的题,POJ一堆求改代码WA的
AC代码

1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 using namespace std; 5 #define MAX 51 6 int G[MAX][MAX]; 7 int lowdis[MAX]; 8 int P; 9 int R; 10 int is_in[MAX]; 11 int ans; 12 int main() 13 { 14 // while(cin>>P>>R && P){ 15 while(cin>>P){ 16 17 if(P==0) 18 return 0; 19 cin>>R; 20 ans=0; 21 22 memset(lowdis,0x3f,sizeof(lowdis)); 23 lowdis[1]=0; 24 25 memset(is_in,0,sizeof(is_in)); 26 is_in[1]=1; 27 memset(G,0x3f,sizeof(G)); 28 for(int i=0;i<R;i++){ 29 int a,b,c; 30 cin>>a>>b>>c; 31 if(G[a][b] > c){ 32 G[a][b]=c; 33 G[b][a]=c; 34 } 35 } 36 for(int i=1;i<=P;i++) 37 G[i][i]=0; 38 for(int i=2;i<=P;i++){ 39 if(lowdis[i]>G[1][i]) 40 lowdis[i]=G[1][i]; 41 } 42 for(int k=1;k<=P-1;k++){ 43 int minx=0x3f3f3f3f; 44 int minid; 45 for(int i=1;i<=P;i++){//找最小 46 if(is_in[i]==0 && minx>lowdis[i]){ 47 minx=lowdis[i]; 48 minid=i; 49 } 50 } 51 is_in[minid]=1; 52 ans+=lowdis[minid]; 53 for(int i=1;i<=P;i++){//更新 54 if(is_in[i]==0 && G[minid][i]<lowdis[i]){ 55 lowdis[i]=G[minid][i]; 56 } 57 } 58 } 59 cout<<ans<<endl; 60 } 61 }
看看其他人咋写的,POJ讨论区说克鲁斯卡尔秒杀,基本和我的模板一模一样挺好,只是边数没给,他自己定的5100,就AC了
通过这个题再次理解了:
点少,边多,就是稠密图,适合普里姆
点多,边少,就是稀疏图,适合克鲁斯卡尔或者堆优化普里姆
关于稀疏稠密我总是分不清,其实可以这样记,一团乱麻就是稠密的,乱麻指的就是点固定,边很多。那点如果很多,边只有零星几条,就是稀疏的
刷题跟应试笔试千差万别,数据结构笔试考察的东西和算法题不一样。有出题人自己的一套思路


浙公网安备 33010602011771号