zoukankan      html  css  js  c++  java
  • POJ1511来回最短路

    POJ1511

    问你从1到其它点得所有最短路之和  与  其他点到1得所有最短路之和 得总和

    思路很明确就是两次最短路,翻转一次地图就好了

    一开始就是两次spfa之间处理好数据得更新管理就好

    vector结构体数组存储边得数据

    dis存储最短路径

    vis表示i是否在队列中

    id与cnt来链式前向星

    需要仔细考虑得不仅仅是spfa算法了,而是开头和中间得跟新优化处理,该初始化的得初始化,初始化成什么值还得清楚

    所以后来我就想用引用和数组指针来做,觉得得快一点吧,因为我用空间换了时间,新一个reedge

    vector结构体数组,在输入的时候存储反向边,对应的还有reid,recnt

    初始化方面不用考虑太多了,需要做的就是函数得参数多了,而这没什么麻烦得

    一开始得code

    #include <iostream>
    #include <queue>
    #include <string.h>
    #include <vector>
    #include <cstdio>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn = 1e6 + 1e2;
    struct node
    {
        int to,cost,pre;
        node(int t,int c,int p):to(t),cost(c),pre(p){}
        node(){}
    };
    vector<node> edge;
    queue<int>q;
    int dis[maxn];
    int vis[maxn];
    int line[maxn][3];
    int id[maxn],cnt;
    void add(int from,int to,int cost)
    {
        edge.push_back(node(to,cost,id[from]));
        id[from] = cnt++;
    }
    void init(int n)
    {
        for(int i = 1;i <= n;i++)
        {
            dis[i] = inf;
            vis[i] = 0;
        }
        edge.clear();
        cnt = 0;
        memset(id,-1,sizeof(id));
    }
    void spfa(int s,int n)
    {
        vis[s] = 1,dis[s] = 0;
        while(q.size())q.pop();
        q.push(s);
    
        while(q.size())
        {
            int now = q.front();q.pop();vis[now] = 0;
            for(int i = id[now];~i;i = edge[i].pre)
            {
                int to = edge[i].to;
                int cost = edge[i].cost;
                if(dis[to] > dis[now] + cost)
                {
                    dis[to] = dis[now] + cost;
                    if(!vis[to])
                    {
                        q.push(to);
                        vis[to] = 1;
                    }
                }
            }
        }
    }
    int main()
    {
        int t,n,m;
        scanf("%d",&t);
        while(t--)
        {
    
            scanf("%d%d",&n,&m);
            init(n);
            int a,b,x;
            for(int i = 0;i < m;i++)
            {
                scanf("%d%d%d",&line[i][0],&line[i][1],&line[i][2]);
                add(line[i][0],line[i][1],line[i][2]);
            }
            spfa(1,n);
            long long ans = 0;
            for(int i = 1;i <= n;i++)
            {
                ans += dis[i];
                dis[i] = inf;
                vis[i] = 0;
            }
            cnt = 0;
            memset(id,-1,sizeof(id));
            edge.clear();
            for(int i = 0;i < m;i++)
            {
                add(line[i][1],line[i][0],line[i][2]);
            }
            spfa(1,n);
            for(int i = 1;i <= n;i++)
            {
                ans += dis[i];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

     后来的

    #include <iostream>
    #include <queue>
    #include <string.h>
    #include <vector>
    #include <cstdio>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn = 1e6 + 1e2;
    struct node
    {
        int to,cost,pre;
        node(int t,int c,int p):to(t),cost(c),pre(p){}
        node(){}
    };
    vector<node> edge,reedge;
    queue<int>q;
    int dis[maxn];
    int vis[maxn];
    int id[maxn],cnt;
    int reid[maxn],recnt;
    void add(int from,int to,int cost,vector<node> &line,int *p,int &num)
    {
        line.push_back(node(to,cost,p[from]));
        p[from] = num++;
    }
    void init(int n)
    {
        for(int i = 1;i <= n;i++)
        {
            dis[i] = inf;
            vis[i] = 0;
        }
        edge.clear();
        reedge.clear();
        cnt = 0;
        recnt = 0;
        memset(id,-1,sizeof(id));
        memset(reid,-1,sizeof(reid));
    }
    void spfa(int s,int n,vector<node> &line,int *p)
    {
        vis[s] = 1,dis[s] = 0;
        while(q.size())q.pop();
        q.push(s);
    
        while(q.size())
        {
            int now = q.front();q.pop();vis[now] = 0;
            for(int i = p[now];~i;i = line[i].pre)
            {
                //cout<<i<<endl;
                int to = line[i].to;
                int cost = line[i].cost;
                if(dis[to] > dis[now] + cost)
                {
                    dis[to] = dis[now] + cost;
                    if(!vis[to])
                    {
                        q.push(to);
                        vis[to] = 1;
                    }
                }
            }
        }
    }
    int main()
    {
        int t,n,m;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            init(n);
            int a,b,x;
            for(int i = 0;i < m;i++)
            {
                scanf("%d%d%d",&a,&b,&x);
                add(a,b,x,edge,id,cnt);
                add(b,a,x,reedge,reid,recnt);
            }
            spfa(1,n,edge,id);
    
            long long ans = 0;
            for(int i = 1;i <= n;i++)
            {
                ans += dis[i];
                dis[i] = inf;
                vis[i] = 0;
            }
            spfa(1,n,reedge,reid);
            for(int i = 1;i <= n;i++)
            {
                ans += dis[i];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

     让我i最不解得是后者竟然没有前者快,而且花了两倍得空间,我觉得可能是引用得问题吧~~其实我也不清楚嘞~

  • 相关阅读:
    HDU 4608 I-number
    hdu 4607 ( Park Visit )
    ZROI十一集训Day2
    CodeForces1230
    模拟退火
    ZROI#1007
    ZROI#1006
    ZROI#1005
    ZROI#1004
    ZROI#962
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/8531421.html
Copyright © 2011-2022 走看看