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\n",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\n",ans);
    }
    return 0;
}

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

posted @ 2018-03-08 23:00  Butterflier  阅读(220)  评论(0编辑  收藏  举报