zoukankan      html  css  js  c++  java
  • POJ 1258 prim模版求最小生成树

    题意:求连接所有村庄的最短路径。就是求最小生成树。

    分析:直接套用prim模版。 POJ 2421在这题上又该进了点。http://www.cnblogs.com/lanjiangzhou/archive/2013/03/25/2981491.html。其实都一样。

    View Code
     // I'm the Topcoder
     //C
     #include <stdio.h>
     #include <stdlib.h>
     #include <string.h>
     #include <ctype.h>
     #include <math.h>
     #include <time.h>
     //C++
     #include <iostream>
     #include <algorithm>
     #include <cstdio>
     #include <cstdlib>
     #include <cmath>
     #include <cstring>
     #include <cctype>
     #include <stack>
     #include <string>
     #include <list>
     #include <queue>
     #include <map>
     #include <vector>
     #include <deque>
     #include <set>
     using namespace std;
    
     //*************************OUTPUT*************************
     #ifdef WIN32
     #define INT64 "%I64d"
     #define UINT64 "%I64u"
     #else
     #define INT64 "%lld"
     #define UINT64 "%llu"
     #endif
    
     //**************************CONSTANT***********************
     #define INF 0x3f3f3f3f
     #define eps 1e-8
     #define PI acos(-1.)
     #define PI2 asin (1.);
     typedef long long LL;
     //typedef __int64 LL;   //codeforces
     typedef unsigned int ui;
     typedef unsigned long long ui64;
     #define MP make_pair
     typedef vector<int> VI;
     typedef pair<int, int> PII;
     #define pb push_back
     #define mp make_pair
    
     //***************************SENTENCE************************
     #define CL(a,b) memset (a, b, sizeof (a))
     #define sqr(a,b) sqrt ((double)(a)*(a) + (double)(b)*(b))
     #define sqr3(a,b,c) sqrt((double)(a)*(a) + (double)(b)*(b) + (double)(c)*(c))
    
     //****************************FUNCTION************************
     template <typename T> double DIS(T va, T vb) { return sqr(va.x - vb.x, va.y - vb.y); }
     template <class T> inline T INTEGER_LEN(T v) { int len = 1; while (v /= 10) ++len; return len; }
     template <typename T> inline T square(T va, T vb) { return va * va + vb * vb; }
    
     // aply for the memory of the stack
     //#pragma comment (linker, "/STACK:1024000000,1024000000")
     //end
    
     #define maxn 2000+10
     int n,m;
     int edge[maxn][maxn];//邻接矩阵
     int lowcost[maxn];
     int nearvex[maxn];
     int sumweight=0;
     void prim(int u0){
         //从顶点u0出发执行普里姆算法
         sumweight=0;//生成树的权值
         for(int i=1;i<=n;i++){
             //初始化lowcost[]数组和neartxt数组
             lowcost[i]=edge[u0][i];
             nearvex[i]=u0;
         }
         nearvex[u0]=-1;
         for(int i=1;i<n;i++){
             int min=INF;
             int v=-1;
             //在lowcoat数组的nearvex[]值为-1的元素中找最小值
             for(int j=1;j<=n;j++){
                 if(nearvex[j]!=-1&&lowcost[j]<min){
                     v=j;
                     min=lowcost[j];
                 }
             }
             if(v!=-1){
                 //v==-1表示没找到权值最小的边
                // printf("%d %d %d\n",nearvex[v],v,lowcost[v]);
                 nearvex[v]=-1;
                 sumweight+=lowcost[v];
                 for(int j=1;j<=n;j++){
                     if(nearvex[j]!=-1&&edge[v][j]<lowcost[j]){
                         lowcost[j]=edge[v][j];
                         nearvex[j]=v;
                     }
                 }
             }
         }
         printf("%d\n",sumweight);
     }
    
     int main(){
         int w;
         while(scanf("%d",&n)!=EOF){
             sumweight=0;
             //memset(edge,0,sizeof(edge));
             for(int i=1;i<=n;i++){
                 for(int j=1;j<=n;j++){
                     edge[i][j]=INF;
                 }
                 edge[i][i]=0;
             }
             for(int i=1;i<=n;i++){
                 for(int j=1;j<=n;j++){
                 scanf("%d",&w);
                 edge[i][j]=w;
                 }
             }
    //         scanf("%d",&m);
    //         for(int i=1;i<=m;i++){
    //             scanf("%d%d",&u,&v);
    //             edge[u][v]=edge[v][u]=0;
    //         }
     //        for(int i=1;i<=n;i++){
     //            for(int j=1;j<=n;j++){
     //                if(i==j) edge[i][j]=0;
     //                else if(edge[i][j]==0 ) edge[i][j]=INF;
     //            }
     //        }
             prim(1);
         }
         return 0;
     }
  • 相关阅读:
    《算法导论》读书笔记之第16章 贪心算法—活动选择问题
    C语言综合实验1—学生信息管理系统
    《算法导论》读书笔记之第15章 动态规划[总结]
    《算法导论》读书笔记之第11章 散列表
    模板类中定义list<T>::iterator iter在g++下不识别的解决办法
    C语言参考程序—无符号一位整数的四则运算
    《算法导论》读书笔记之第15章 动态规划—最优二叉查找树
    C语言综合实验2—长整数运算
    递归与尾递归总结
    《算法导论》读书笔记之第13章 红黑树
  • 原文地址:https://www.cnblogs.com/lanjiangzhou/p/2982327.html
Copyright © 2011-2022 走看看