• POJ 1258 Agri-Net(最小生成树,模板题)


    用的是prim算法。

    我用vector数组,每次求最小的dis时,不需要遍历所有的点,只需要遍历之前加入到vector数组中的点(即dis[v]!=INF的点)。
    但其实时间也差不多,和遍历所有的点的方法都是16ms。。。

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <stdio.h>
    #include <string>
    #include <queue>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    int n,cost;
    int ans;
    int w[101][101];
    int dis[101]; //生成树外的点与生成树相连的最短边长
    int pre[101]; //pre[v]为v的前驱节点,用来输出进入最小生成树的边。该题用不到
    int vis[101]; //标记点是否在生成树中
    vector<int> son[101];
    
    void init() {
        memset(pre,0,sizeof(pre));
        memset(dis,INF,sizeof(dis));
        memset(vis,0,sizeof(vis));
    }
    
    int solve() {
        vector<int> node;
        int s=1,counts=0,ans=0,tmp,k;
        dis[s]=0;
        pre[s]=s;
    
        node.push_back(s);
        while(1) {
            tmp=INF;
    
            for(int i=0; i<node.size(); i++) {
                int v=node[i];
                if(!vis[v]&& dis[v]<tmp) {
                    tmp=dis[v];
                    k=v;   //k即为在没有进入最小生成树的点中到树的距离(dis[k])最小的点。
                }
            }
            /*
            //直接遍历所有的点
            for(int i=1;i<=n;i++){
                if(!vis[i]){
                    if(dis[i]<tmp){
                        tmp=dis[i];
                        k=i;
                    }
                }
            }
            */
            if(tmp==INF)
                break;
            ans+=tmp;
            vis[k]=1;
    
            for(int i=0; i<son[k].size(); i++) {
                int v=son[k][i];
                if(!vis[v] && w[k][v]<dis[v]) {
                    dis[v]=w[k][v];
                    pre[v]=k;
                    node.push_back(v);
                }
            }
        }
        return ans;
    
    }
    int main() {
        while(scanf("%d",&n)!=EOF) {
    
            for(int i=0; i<101; i++) {
                son[i].clear();
            }
            for(int i=1; i<=n; i++) {
                for(int j=1; j<=i; j++)
                    scanf("%d",&cost);
                for(int j=i+1; j<=n; j++) {
                    scanf("%d",&cost);
                    w[i][j]=w[j][i]=cost;
                    son[i].push_back(j);
                    son[j].push_back(i);
                }
            }
            ans=0;
            init();
            ans=solve();
    
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    常用数据绑定控件详解
    BookList
    BUG:TreeView: NodeCheck Event Does Not Occur
    SQL Server中TEXT类型操作
    Quote:软件开发工程师的经验之谈
    SQL字符串处理函数大全
    Summary 2009 Target 2010
    读取库中的所有表名 列名
    使用大值数据类型
    sql 修改列名及表名 sp_rename
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3373439.html
Copyright © 2020-2023  润新知