HDU 1233 还是畅通工程(最小生成树)
2014-12-31 01:44
323 查看
仔细想想这就是一道最裸的最小生成树题目
这里给出prim和kruscal两种方法计算
当然因为这题目是密集边
所以其实prim算法更加好一点的
prim:
kruscal:
这里给出prim和kruscal两种方法计算
当然因为这题目是密集边
所以其实prim算法更加好一点的
prim:
/* 最小生成树,prim算法 */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 105; const int INF = 0x3f3f3f3f; int k , fa , minn , first , vis ;//vis 表示是否添入以保存的集合 struct Edge{ int y , next , d; bool operator<(const Edge & m )const{ return d < m.d; } }e[N*N]; void add_edge(int x , int y, int d) { e[k].y = y , e[k].next = first[x] , e[k].d = d; first[x] = k++; } int prim(int src , int n) { memset(minn , 0x3f , sizeof(minn)); memset(vis , 0 , sizeof(vis)); vis[src] = 1; for(int i = first[src] ; i!=-1 ; i=e[i].next) { int v = e[i].y; if(!vis[v]) minn[v] = min(minn[v] , e[i].d); } int ans = 0; for(int i = 1 ; i<n ; i++) { int index = 0 , Min = INF; for(int j = 1 ; j<=n ; j++) { if(minn[j] < Min){ Min = minn[j]; index = j; } } ans += Min; minn[index] = INF; vis[index] = 1; //使index不能再被访问 //更新 for(int j = first[index] ; j!=-1 ; j=e[j].next) { int v = e[j].y; if(!vis[v]) minn[v] = min(minn[v] , e[j].d); } } return ans; } int main() { // freopen("a.in" , "r" , stdin); int n , m , a , b , d; while(scanf("%d" , &n) , n) { m = n*(n-1) / 2; for(int i = 1 ; i<=n ; i++) fa[i] = i; k = 0; memset(first , -1 , sizeof(first)); for(int i = 0 ; i<m ; i++){ scanf("%d%d%d" , &a , &b , &d); add_edge(a , b , d); add_edge(b , a , d); } printf("%d\n" , prim(1 , n)); } return 0; }
kruscal:
/* 最小生成树,prim算法 */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 105; int k , fa ; struct Edge{ int x , y , d; bool operator<(const Edge & m )const{ return d < m.d; } }e[N*N]; void add_edge(int x , int y, int d) { e[k].x = x , e[k].y = y , e[k].d = d; k++; } int get_head(int x) { while(x != fa[x]) x=fa[x]; return x; } bool Union(int x , int y) { int fa_x = get_head(x); int fa_y = get_head(y); if(fa_x != fa_y){ fa[fa_x] = fa_y; return true; } return false; } int main() { // freopen("a.in" , "r" , stdin); int n , m , a , b , d; while(scanf("%d" , &n) , n) { k = 0; m = n*(n-1) / 2; for(int i = 1 ; i<=n ; i++) fa[i] = i; for(int i = 0 ; i<m ; i++){ scanf("%d%d%d" , &a , &b , &d); add_edge(a , b , d); } sort(e , e+k); int ans = 0; for(int i = 0 ; i<k ; i++){ if(Union(e[i].x , e[i].y)) ans += e[i].d; } printf("%d\n" , ans); } return 0; }
相关文章推荐
- hdu 1233 还是畅通工程(最小生成树)
- HDU 1233 还是畅通工程(最小生成树)
- hdu 1233 还是畅通工程(最小生成树Kruskal)
- HDU 1233 还是畅通工程(最小生成树,prim)
- HDU-1233 还是畅通工程 (prim 算法求最小生成树)
- HDU - 1233 - 还是畅通工程 (最小生成树!!)
- hdu 1233 还是畅通工程(最小生成树,kruskal,前向星)
- hdu1233——还是畅通工程(最小生成树)
- HDU-1233-还是畅通工程(最小生成树 克鲁斯卡尔)
- hdu 1233 还是畅通工程(最小生成树)
- hdu 1233 最小生成树 "还是畅通工程"
- hdu 1233 还是畅通工程(最小生成树)
- poj1258 Agri-Net +hdu 1233 还是畅通工程 (最小生成树Prime算法)
- [HDU 1233] 还是畅通工程(最小生成树)
- HDU 1233-还是畅通工程(最小生成树)
- hdu 1233 还是畅通工程(最小生成树prim)
- hdu 1233 还是畅通工程(最小生成树的Prim和Kruskal两种算法的c++实现)(prim算法详解)
- HDU 1233 还是畅通工程(最小生成树Kruskal)
- hdu 1233 还是畅通工程(最小生成树,基础)
- HDU - 1233 还是畅通工程(最小生成树)