zoukankan      html  css  js  c++  java
  • poj1258 AgriNet **

    /*
    * 纯粹的最短路 prim 用 二叉堆 实现
    *
    * 用二叉堆实现优先级队列 比较麻烦~ 后面附上直接用数组的
    *
    */
    #include
    <cstdio>
    #include
    <cstring>
    usingnamespace std;

    constint maxN =100+5;
    constint inf =100000000;
    int n, G[maxN][maxN], len; //len:二叉堆数组的长度
    int ans;
    bool S[maxN];
    int d[maxN], vertex[maxN], reverse[maxN]; //二叉堆中节点的域

    int inline left(int i){ return2* i; }
    int inline right(int i){ return2* i +1; }
    int inline p(int i){ return i/2; }

    void inline swap(int lhs, int rhs){
    int tmp = d[lhs]; d[lhs] = d[rhs]; d[rhs] = tmp;
    tmp
    = vertex[lhs]; vertex[lhs] = vertex[rhs]; vertex[rhs] = tmp;
    reverse[vertex[lhs]]
    = lhs; reverse[vertex[rhs]] = rhs;
    }

    //二叉堆操作
    void minHeapify(int i){
    int l = left(i);
    int r = right(i);

    int tmpMinNum = i;
    int tmpMinD = d[i];
    if(l < len && d[l] < tmpMinD){
    tmpMinNum
    = l;
    tmpMinD
    = d[l];
    }
    if(r < len && d[r] < tmpMinD){
    tmpMinNum
    = r;
    tmpMinD
    = d[r];
    }
    if(tmpMinNum != i){
    swap(i, tmpMinNum);
    minHeapify(tmpMinNum);
    }
    }

    void makeHeap(){
    for(int i=0; i<n; i++){
    d[i]
    = inf; vertex[i] = reverse[i] = i;
    }
    d[
    0] =0;

    len
    = n;
    }

    int minimumD(){ return d[0]; }
    int minimumVertex() { return vertex[0]; }

    int extractMin(){
    int ans = minimumD();
    swap(
    0, len-1);
    len
    --;
    minHeapify(
    0);

    return ans;
    }

    void decreaseKey(int i, int key){
    d[i]
    = key;
    while(i !=0&& d[i] < d[p(i)]){
    swap(i, p(i));
    i
    = p(i);
    }
    }

    //MST-Prim
    int mstPrim(){
    makeHeap();

    while(len !=0){
    int minVertex = minimumVertex();
    S[minVertex]
    =1;
    int tmp = extractMin();
    ans
    += tmp;

    for(int i=0; i<n; i++){
    if(S[i] ==0&& G[i][minVertex] < d[reverse[i]]){
    decreaseKey(reverse[i], G[i][minVertex]);
    }
    }
    }
    return ans;
    }


    int main(){
    while(scanf("%d", &n) != EOF){
    for(int i=0; i<n; i++)
    for(int j=0; j<n; j++)
    scanf(
    "%d", &G[i][j]);

    memset(S,
    0, sizeof(S));
    ans
    =0;

    mstPrim();

    printf(
    "%d\n", ans);
    }



    return0;
    }

        

        

    ————————

        

     

    /*
    * STL priority_queue 实现
    *
    */

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;

    const int maxn = 100 + 5;
    const int inf = 10000000;

    int n, m[maxn][maxn];
    int dis[maxn];
    bool vis[maxn];

    struct SNode{
    int index;
    int dis;

    friend bool operator<(const SNode &a, const SNode &b){ //注意如何重载!!
    //friend
    return a.dis > b.dis;
    }
    };
    SNode node[maxn];

    int prim(){
    int ans = 0;

    for(int i=0; i<n; i++){
    node[i].index = i;
    node[i].dis = inf;
    }
    node[0].dis = 0;

    priority_queue<SNode> q;
    q.push(node[0]);

    bool found = 0;
    SNode cur;
    for(int i=0; i<n; i++){
    found = 0;
    while(!q.empty()){
    cur = q.top();
    q.pop();

    if(!vis[cur.index]){
    found = 1;
    break;
    }
    }

    if(!found) break;

    ans += cur.dis;

    int v = cur.index;
    vis[v] = 1; //别忘了更新vis
    for(int j=0; j<n; j++){
    if(!vis[j] && m[v][j] < node[j].dis){
    node[j].dis = m[v][j];
    q.push(node[j]);
    }
    }
    }

    return ans;
    }

    int main(){
    while(scanf("%d", &n) == 1){
    for(int i=0; i<n; i++){
    for(int j=0; j<n; j++){
    scanf("%d", &m[i][j]);
    }
    }

    for(int i=0; i<n; i++)
    dis[i] = inf;
    memset(vis, 0, sizeof(vis));

    int ans = prim();

    printf("%d\n", ans);

    }


    return 0;
    }

      

     ——————————   

          

    #include<cstdio>
    usingnamespace std;
    constint Max =102;
    constint inf =0xfffffff;


    int n, ans;
    int map[Max][Max], dis[Max]; // dis[i]表示顶点i与生成树之间的最短距离。


    int min(int a, int b){
    return a < b ? a : b;
    }

    void prim(){ // 自己的prim模板。
    int i, j, now, min_node, min_edge;
    for(i =1; i <= n; i ++)
    dis[i]
    = inf;
    now
    =1;
    ans
    =0;
    for(i =1; i < n; i ++){
    dis[now]
    =-1; // 将dis[]的值赋-1,表示已经加入生成树中。
    min_edge = inf;
    for(j =1; j <= n; j ++) // 更新每个顶点所对应的dis[]值。
    if(now != j && dis[j] >=0){
    dis[j]
    = min(dis[j], map[now][j]);
    if(dis[j] < min_edge){
    min_edge
    = dis[j];
    min_node
    = j;
    }
    }
    now
    = min_node;
    ans
    += min_edge;
    }
    }


    int main(){
    int i, j;
    while(scanf("%d", &n) != EOF){
    for(i =1; i <= n; i ++)
    for(j =1; j <= n; j ++)
    scanf(
    "%d", &map[i][j]);
    prim();
    printf(
    "%d\n", ans);
    }
    return0;
    }
  • 相关阅读:
    实验四: Android程序设计
    实验三 敏捷开发与XP实践-1
    mini dc课堂练习补交
    20155216 2016-2017-2 《Java程序设计》第十周学习总结
    第十二周课上练习
    20155210 潘滢昊 Java第三次实验
    20155210 2016-2017-2 《Java程序设计》第10周学习总结
    20155210 潘滢昊2016-2017-2 《Java程序设计》第9周学习总结
    20155210潘滢昊 Java第二次试验
    20155210潘滢昊 2016-2017-2 《Java程序设计》第8周学习总结
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2163416.html
Copyright © 2011-2022 走看看