yzoj P1412 & 洛谷P1629 邮递员送信 题解

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

很容易发现我们要求 \(\sum_{j=1}^n\) dis[1][ j ]+dis[ j ][1],可以想到跑spfa,对于dis[1][ j ]可以一遍spfa解决但是对于 dis[ j ][1]却不好解决,如果跑n遍spfa明显超时,但我们可以换个思路,建立反图,对节点1跑spfa,那么1节点到别的点的距离就是别的点到1节点的距离。

代码

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
const int N=1010,M=100010;
int head[N][2],ver[M][2],edge[M][2],Next[M][2],d[N][2];
int n,m,tot1,tot2;
long long ans;
bool v[N];
queue<int> q;
void add(int x,int y,int z){
    ver[++tot1][0]=y;edge[tot1][0]=z;Next[tot1][0]=head[x][0],head[x][0]=tot1;
}
void add1(int x,int y,int z){
    ver[++tot2][1]=y;edge[tot2][1]=z;Next[tot2][1]=head[x][1],head[x][1]=tot2;
}
void spfa(){
    memset(d,0x3f,sizeof(d));
    d[1][0]=0,v[1]=1;
    q.push(1);
    while(q.size()){
        int x=q.front();q.pop();
        v[x]=0;
        for(int i=head[x][0];i;i=Next[i][0]){
            int y=ver[i][0],z=edge[i][0];
            if(d[y][0]>d[x][0]+z){
                d[y][0]=d[x][0]+z;
                if(!v[y]) q.push(y),v[y]=1;
            }
        }
    }
    while(!q.empty()) q.pop();
    memset(v,0,sizeof(v));
    d[1][1]=0,v[1]=1;
    q.push(1);
    while(q.size()){
        int x=q.front();q.pop();
        v[x]=0;
        for(int i=head[x][1];i;i=Next[i][1]){
            int y=ver[i][1],z=edge[i][1];
            if(d[y][1]>d[x][1]+z){
                d[y][1]=d[x][1]+z;
                if(!v[y]) q.push(y),v[y]=1;
            }
        }
    }
}
int main(){
    n=read();m=read();
    for(int i=1;i<=m;++i){
        int x,y,z;
        x=read();y=read();z=read();
        add(x,y,z);
        add1(y,x,z);
    }
    spfa();
    for(int i=1;i<=n;++i){
        ans+=d[i][0]+d[i][1];
    }
    printf("%lld",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/donkey2603089141/p/11416583.html
今日推荐