poj1258

学习算法,感觉到理论和实践还是有很大不同的,就算理解了一个算法,但也只有真正能用它来解决一个问题的时候才能算掌握了。算法的道路,行之不易,且行且珍惜。把学到的算法和A过的题总结在这里,当做是一个学习的过程吧。好了,废话不多说,看题目。
题目在这里,可以参考。http://poj.org/problem?id=1258

题意分析:大意就是说一个农民当上了镇长,然后他想把所有农民通过网络联系起来,自然的,这就涉及到了布设线路的费用问题,所以分析至此,我们就明白了,这是一道求最小生成树的问题,题目输入一个n,代表农民,也就是点的个数,然后输入一个矩阵,保存每两个点之间的权值,在本题中就是购买光纤的钱数,要求输出最少花费,也即最小生成树的权值和。

解法:最小生成树可以用prim算法或者是kruskal算法,我在这里用了prim算法。

上代码:
#include <iostream>
    #include <string.h>
    using namespace std;
    #define inf 2000000
    int prim(int matrix[105][105],int n)
    {
        bool visit[105];
        int result=0;
        int p[n];
        for(int i=1;i<=n;i++)
        {
            p[i] = matrix[1][i];
            memset(visit,0,sizeof(visit));
        }       
        for(int i=1;i<=n;i++)
        {
            int min=inf;
            int index=0;
            for(int j=1;j<=n;j++)
            {
                if(p[j]<min&&visit[j]==0)
                {
                    min = p[j];
                    index = j;
                }
            }
            result+=p[index];
            visit[index] = 1;
            //p[index]=0;
            for(int j=1;j<=n;j++)
            {
                if(!visit[j])p[j] = matrix[index][j]<p[j]?matrix[index][j]:p[j];
            }
        }
    // for(int i=1;i<=n;i++)
    // cout<<"p[i]"<<p[i]<<endl; 
        return result;
    }
    int main()
    {
        int n;
        int matrix[105][105];
        while(cin>>n)
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    matrix[i][j] = inf;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    cin>>matrix[i][j];
            cout<<prim(matrix,n)<<endl;             
        }
        return 0;
    }`

你可能感兴趣的:(算法)