HDU1863 - 畅通工程:http://acm.hdu.edu.cn/showproblem.php?pid=1863
这题我中午用并查集的方法AC了一次,下午学了Prim。换个姿势,再来一次 = =!
并查集的方法:http://blog.csdn.net/p_rogrammer/article/details/47979073
代码:
#include <iostream> #include <cstdio> #include <vector> #include <cstring> using namespace std; const int MAXN = 111; const int Inf = 1<<31 - 1; int N,M; int x,y,z; vector<int>Mapp[MAXN]; int Cost[MAXN][MAXN],vis[MAXN],Distance[MAXN]; void Initial() { for(int i = 0;i < MAXN;i++) Mapp[i].clear(); fill(vis,vis + MAXN,0); fill(Distance,Distance + MAXN,Inf); } int Prim() { int ans = 0, cnt = 0; Distance[1] = 0; while(true) { int v = -1;//每次都要从第一个村庄开始查找距离 已经连好的村庄 最近的村庄的编号 v for(int i = 1;i <= M;i++) if(!vis[i] && (v == -1 || Distance[i] < Distance[v])) v = i; // printf("v = %d\n",v); if(v == -1 || Distance[v] == Inf)return -1; ans += Distance[v]; // printf("ans = %d\n",ans); cnt++;//已经连在一起的村庄的数目 if(cnt == M)return ans; vis[v] = 1;//村庄v标记为访问过 // printf("vis[%d] = %d\n",v,vis[v]); for(int i = 0;i < Mapp[v].size();i++) { int x = Mapp[v][i];//x是与v相连的村庄编号 if(!vis[x] && Cost[v][x] < Distance[x])Distance[x] = Cost[v][x];//更新到已连好的村庄的距离,保证是最短的 } } } int main() { while(~scanf("%d",&N) && N) { scanf("%d",&M); Initial(); while(N--) { scanf("%d%d%d",&x,&y,&z); if(x != y) { Mapp[x].push_back(y); Mapp[y].push_back(x); Cost[x][y] = Cost[y][x] = z;//无向的图,x可到y,y可到x,上同 } } int flag = Prim(); if(flag == -1)printf("?\n"); else printf("%d\n",flag); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/p_rogrammer/article/details/47981653