题解 P1629 【邮递员送信】

2018-08-06 00:00:00 题解

抄代码的人RE!

(第一次写题解,有点小激动) 其实这一题也是卡了我好久的,就因为题目意思理解错了(虽然是一遍过) 先讲一下思路 邮递员要送N-1样东西&&这个邮递员每次只能带一样东西,也就是求从1点出发,到其他每一个点走一个来回的最短距离和; 思路就来了: 思路一:跑n遍Dijkstra,依次求出从1点出发,到其他每一个点走一个来回的最短距离。 结果------原地爆炸------3个TLE; 思路二:跑两遍Dijkstra 跑两遍怎么就能求的出来呢?
       第一遍:毫无疑问求出1到其他每一个点走一遍的最短距离;
       第二遍:反向存图,从每个点到1的最短距离;
然后相加就好啦 结果--------

恭喜你通过了此题!!!

~代码来也~~~

#include<bits/stdc++.h>//万能头文件
#define MAXN 1001//定义常量
#define MAXM 100001//同上
#define lots_of_money namespace std
using lots_of_money//路费
struct edge//数组模拟临接表储存
{
    int to;
    int next;
    int val;
}edg1[MAXM],edg2[MAXM];
int dis1[MAXN],dis2[MAXN];
int head1[MAXN],head2[MAXN];
bool vis[MAXN];
int dis[MAXN];
int top=0;//边的个数
int total;//最终答案
int n,m;
void join(int u,int v,int val)//存储一条边
{
    top++;
    edg1[top].next=head1[u];//正向存储
    edg1[top].to=v;
    edg1[top].val=val;
    head1[u]=top;

    edg2[top].next=head2[v];//反向存储
    edg2[top].to=u;
    edg2[top].val=val;
    head2[v]=top;
}
void into()//输入
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u,v,val;
        cin>>u>>v>>val;
        join(u,v,val);
    }
}
void csh()//初始化
{
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=n;i++)
        dis[i]=INT_MAX;
    dis[1]=0;
}
void djstl(edge *edge,int *head)//传数组用指针
{
    for(int l=1;l<n;l++)//Dijkstra
    {
        int k=0,minn=INT_MAX;
        for(int i=1;i<=n;i++)
            if(!vis[i]&&dis[i]<minn)
                minn=dis[k=i];
        if(k==0) break;
        vis[k]=1;
        for(int i=head[k];i;i=edge[i].next)
            if(dis[k]+edge[i].val<dis[edge[i].to])
                dis[edge[i].to]=dis[k]+edge[i].val;
    }
}
int main()
{
    into();
    csh();
    djstl(edg1,head1);
    for(int i=2;i<=n;i++)//加上去的时间
        total+=dis[i];
    csh();
    djstl(edg2,head2);
    for(int i=2;i<=n;i++)//加上回来的时间
        total+=dis[i];
    cout<<total<<endl;
    return true;
}

离别多

2025-01-07 20:20:21

研表究明,汉字的序顺并不定一能影阅响读,比如当你看完这句话后,才发这现里的字全是都乱的。 http://appdownload.cc