首页 > 代码库 > HDU 1233 还是畅通工程(最小生成树)
HDU 1233 还是畅通工程(最小生成树)
仔细想想这就是一道最裸的最小生成树题目
这里给出prim和kruscal两种方法计算
当然因为这题目是密集边
所以其实prim算法更加好一点的
prim:
1 /* 2 最小生成树,prim算法 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 8 using namespace std; 9 const int N = 105;10 const int INF = 0x3f3f3f3f;11 12 int k , fa[N] , minn[N] , first[N] , vis[N];//vis[N]表示是否添入以保存的集合13 14 struct Edge{15 int y , next , d;16 bool operator<(const Edge & m )const{17 return d < m.d;18 }19 }e[N*N];20 21 void add_edge(int x , int y, int d)22 {23 e[k].y = y , e[k].next = first[x] , e[k].d = d;24 first[x] = k++;25 }26 27 int prim(int src , int n)28 {29 memset(minn , 0x3f , sizeof(minn));30 memset(vis , 0 , sizeof(vis));31 vis[src] = 1;32 for(int i = first[src] ; i!=-1 ; i=e[i].next)33 {34 int v = e[i].y;35 if(!vis[v]) minn[v] = min(minn[v] , e[i].d);36 }37 int ans = 0;38 for(int i = 1 ; i<n ; i++)39 {40 int index = 0 , Min = INF;41 for(int j = 1 ; j<=n ; j++)42 {43 if(minn[j] < Min){44 Min = minn[j];45 index = j;46 }47 }48 ans += Min;49 minn[index] = INF;50 vis[index] = 1; //使index不能再被访问51 //更新52 for(int j = first[index] ; j!=-1 ; j=e[j].next)53 {54 int v = e[j].y;55 if(!vis[v]) minn[v] = min(minn[v] , e[j].d);56 }57 }58 return ans;59 }60 61 int main()62 {63 // freopen("a.in" , "r" , stdin);64 int n , m , a , b , d;65 while(scanf("%d" , &n) , n)66 {67 m = n*(n-1) / 2;68 for(int i = 1 ; i<=n ; i++) fa[i] = i;69 70 k = 0;71 memset(first , -1 , sizeof(first));72 for(int i = 0 ; i<m ; i++){73 scanf("%d%d%d" , &a , &b , &d);74 add_edge(a , b , d);75 add_edge(b , a , d);76 }77 78 printf("%d\n" , prim(1 , n));79 }80 return 0;81 }
kruscal:
1 /* 2 最小生成树,prim算法 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 8 using namespace std; 9 const int N = 105;10 11 int k , fa[N];12 13 struct Edge{14 int x , y , d;15 bool operator<(const Edge & m )const{16 return d < m.d;17 }18 }e[N*N];19 20 void add_edge(int x , int y, int d)21 {22 e[k].x = x , e[k].y = y , e[k].d = d;23 k++;24 }25 26 int get_head(int x)27 {28 while(x != fa[x]) x=fa[x];29 return x;30 }31 32 bool Union(int x , int y)33 {34 int fa_x = get_head(x);35 int fa_y = get_head(y);36 if(fa_x != fa_y){37 fa[fa_x] = fa_y;38 return true;39 }40 return false;41 }42 43 int main()44 {45 // freopen("a.in" , "r" , stdin);46 int n , m , a , b , d;47 while(scanf("%d" , &n) , n)48 {49 k = 0;50 m = n*(n-1) / 2;51 52 for(int i = 1 ; i<=n ; i++) fa[i] = i;53 54 for(int i = 0 ; i<m ; i++){55 scanf("%d%d%d" , &a , &b , &d);56 add_edge(a , b , d);57 }58 sort(e , e+k);59 int ans = 0;60 for(int i = 0 ; i<k ; i++){61 if(Union(e[i].x , e[i].y)) ans += e[i].d;62 }63 printf("%d\n" , ans);64 }65 return 0;66 }
HDU 1233 还是畅通工程(最小生成树)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。