您的位置:首页 > 其它

poj 1511 最短路

2013-08-24 14:52 549 查看
传送门

题意:学生们去站点工作吧,从1出发,n-1个站点,每个站点都有学生,最后回到学校,给你很多路径,问最少车费。

思路:可以看作n-1个学生,分别去n-1个站点,最后再回到学校吧。然后答案就是1到n-1个点的最短路的和加上n-1个点到1的最短路的和。

前面的很简单,以1为起点求单源最短路就能求出1到n-1个站点的最短路和。

至于后者,由于n很大,路也很多,以每个点为起点求到1的最短路显然不现实,然后想想它们的终点都是1,于是可以选择从1出发,按逆向路求出到n-1个点的最短路即可。

吐槽:最后答案要long long 范围。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 1<<30
using namespace std;
int t,m,n;
int fst1[1000005],next1[1000005],node1[1000005],en1;
int fst2[1000005],next2[1000005],node2[1000005],en2;
int l1[1000005],d1[1000005],l2[1000005],d2[1000005];
long long int ans;
bool in[1000005];
void init()
{
    int u,v,l;
    en1=0;
    en2=0;
    memset(fst1,-1,sizeof(fst1));
    memset(fst2,-1,sizeof(fst2));
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&u,&v,&l);
        next1[++en1]=fst1[u];
        fst1[u]=en1;
        node1[en1]=v;
        l1[en1]=l;

        next2[++en2]=fst2[v];
        fst2[v]=en2;
        node2[en2]=u;
        l2[en2]=l;
    }
}
void spfa1(int s)
{
    int u,v;
    for(int i=1;i<=n;i++)d1[i]=maxn;
    d1[s]=0;
    queue<int>q;
    memset(in,0,sizeof(in));
    q.push(s);
    in[s]=1;
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        in[u]=0;
        for(int i=fst1[u];i!=-1;i=next1[i])
        {
            v=node1[i];
            if(d1[v]>d1[u]+l1[i])
            {
                d1[v]=d1[u]+l1[i];
                if(!in[v])
                {
                    q.push(v);
                    in[v]=1;
                }
            }
        }
    }
}
void spfa2(int s)
{
    int u,v;
    for(int i=1;i<=n;i++)d2[i]=maxn;
    d2[s]=0;
    queue<int>q;
    memset(in,0,sizeof(in));
    q.push(s);
    in[s]=1;
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        in[u]=0;
        for(int i=fst2[u];i!=-1;i=next2[i])
        {
            v=node2[i];
            if(d2[v]>d2[u]+l2[i])
            {
                d2[v]=d2[u]+l2[i];
                if(!in[v])
                {
                    q.push(v);
                    in[v]=1;
                }
            }
        }
    }
}
void solve()
{
    spfa1(1);
    spfa2(1);
    ans=0;
    for(int i=2;i<=n;i++)
    {
        ans+=d1[i]+d2[i];
    }
    printf("%lld\n",ans);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        init();
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: