P1629 邮递员送信

2018-06-17 22:00:25来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

题目描述: 
有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间。这个邮递员每次只能带一样东西。求送完这N-1样东西并且最终回到邮局最少需要多少时间。

输入格式: 
第一行包括两个整数N和M。 
第2到第M+1行,每行三个数字U、V、W,表示从A到B有一条需要W时间的道路。 满足1<=U,V<=N,1<=W<=10000,输入保证任意两点都能互相到达。

输出格式: 
输出仅一行,包含一个整数,为最少需要的时间。

数据规模: 
对于30%的数据,有1≤N≤200; 
对于100%的数据,有1≤N≤1000,1≤M≤100000。

 

思路 :

这是一道最短路问题,SPFA算法可以很好的解决。但是题目特殊在最后需要的并不是单一两点间的最短路,而是1到2~N每个点来回最短路程的总和,所以需要以1点为起点做一次SPFA,得到1点到每个点的最短路。而后处理每个点到1之间的最短路。可以将边反向,以求得N个点到1的最短距离,首先运用三个数组U,V,W记录输入的参数,在跑完1到每个点的最短路后,清空vis数组和存储路径信息的邻接表,初始化dis数组,(Tips:各位初次写没初始化的萌新,这里的初始化很重要!!),然后对U,V,W进行遍历,本来为U->V边权为W的路径在这里方向进行反向存储了!!现在要存储的应该是V->U边权为W的路径。这样再一次以1为起点进行一次SPFA,便可以的到每个点到1的最短路(Tips:这里相当于将所有路径反向,也就相当于把1作为终点去找每个点为起点时的返程的最短路

#include<iostream>  
#include<cstring>  
#include<cstdio>  
#include<queue>  
using namespace std;  
const int N=1005;  
const int M=100005;  
int n,m,cnt,ans,hd[N],dis[N],a[M],b[M],c[M];  
bool inq[N];  
queue<int>q;  
struct edge  
{  
    int to,nxt,val;  
}v[M];  
void addedge(int x,int y,int z)  
{  
    ++cnt;  
    v[cnt].to=y;  
    v[cnt].nxt=hd[x];  
    v[cnt].val=z;  
    hd[x]=cnt;  
}  
int main()  
{  
    scanf("%d%d",&n,&m);  
    for(int i=1;i<=m;i++)  
    {  
        scanf("%d%d%d",&a[i],&b[i],&c[i]);  
        addedge(a[i],b[i],c[i]);  
    }  
    memset(dis,0x3f,sizeof(dis));  
    dis[1]=0;  
    q.push(1);  
    inq[1]=1;  
    while(!q.empty())  
    {  
        int u=q.front();  
        q.pop();  
        inq[u]=0;  
        for(int i=hd[u];i;i=v[i].nxt)  
            if(dis[v[i].to]>dis[u]+v[i].val)  
            {  
                dis[v[i].to]=dis[u]+v[i].val;  
                if(!inq[v[i].to])  
                {  
                    inq[v[i].to]=1;  
                    q.push(v[i].to);  
                }  
            }  
    }  
    for(int i=2;i<=n;i++)  
        ans+=dis[i];  
    memset(v,0,sizeof(v));  
    memset(hd,0,sizeof(hd));  
    cnt=0;  
    for(int i=1;i<=m;i++)  
        addedge(b[i],a[i],c[i]);  
    memset(dis,0x3f,sizeof(dis));  
    dis[1]=0;  
    q.push(1);  
    inq[1]=1;  
    while(!q.empty())  
    {  
        int u=q.front();  
        q.pop();  
        inq[u]=0;  
        for(int i=hd[u];i;i=v[i].nxt)  
            if(dis[v[i].to]>dis[u]+v[i].val)  
            {  
                dis[v[i].to]=dis[u]+v[i].val;  
                if(!inq[v[i].to])  
                {  
                    inq[v[i].to]=1;  
                    q.push(v[i].to);  
                }  
            }  
    }  
    for(int i=2;i<=n;i++)  
        ans+=dis[i];  
    printf("%d\n",ans);  
    return 0;  
}  

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:由可变参数引起的崩溃

下一篇:分享一些好的文章,致曾经苦苦思索的我