邮递员送信_lduoj_最短路

简介: 邮递员送信Description有一个邮递员要送东西,邮局在结点1。他总共要送N−1样东西,其目的地分别是2−N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共M条道路,通过每条道路需要一定的时间。这个邮递员每次只能带一样东西。求送完这N−1样东西并且最终回到邮局最少需要多少时间。Input输入文件第一行包括一个正整数N和M;接下来M行,每行三个正整数U,V,W,表示该条道路为从U到V的,且通过这条道路需要W的时间。满足1 <= U,V、N <= 1000 , 1≤W≤10000,输入保证任意两点都能互相到达。Output输出仅一行,包含一个整数,为最少需要的时间。

邮递员送信


Description


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


Input


输入文件第一行包括一个正整数N和M;

接下来M行,每行三个正整数U,V,W,表示该条道路为从U到V的,且通过这条道路需要W的时间。满足1 <= U,V、N <= 1000 , 1≤W≤10000,输入保证任意两点都能互相到达。


Output


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


Samples


Input Copy

5 10
2 3 5
1 5 5
3 5 6
1 2 8
1 3 8
5 3 4
4 1 8
4 5 3
3 5 6
5 4 2


Output

83


Hint

对于30%的数据,满足1≤N≤200

对于100%的数据,满足1≤N≤1000,1≤M≤100000


本体需要注意的是点之间联通的关系为单向边,就不能用 dis[i] 代表目标点到起点的最短距离,只能表示起点到目标点的最短距离

对于从起点到目标点的情况下来说,我们可以通过按照输入顺序 u v w,建一条从u到v且边权为w的有向边

对于从目标点返回起点的情况来讲,我们可以通过按照与输入顺序 u v w 相反的顺序建立从 v 到 u 且边权为 w 的有向边,建立反图(多起点,单一终点)

这个题可以建立两个独立的图网络,跑两次Dijkstra,为了方便,也可以在建立第二个图网络的时候将所有点的编号加上 n ,得到建立的反图


注意下边权和标记数组的初始化


Main_Code():


int n,m;
int head[maxn];
struct node{
    int u;
    int v;
    int w;
    int next;
}e[maxn];
int cnt = 0;
void add(int u,int v,int w){
    e[cnt].u = u;
    e[cnt].v = v;
    e[cnt].w = w;
    e[cnt].next = head[u];
    head[u] = cnt++;
}
int dis[maxn];
bool vis[maxn];
void init(){
    for(int i=1;i<maxn;i++) {
        dis[i] = 0x3f3f3f3f;
        vis[i] = 0;
        ///head[i] = -1;
    }
}
struct edg{
    int pnt;
    int dist;
    bool operator < (const  edg&aaa) const{
        return dist > aaa.dist;
    }
};
void dij(int st){
    priority_queue<edg> que;
    dis[st] = 0;
    que.push((edg){st,0});
    while(que.size()){
        edg cur = que.top();
        que.pop();
        int pu = cur.pnt;
        int d = cur.dist;
        if(vis[pu]) continue;
        vis[pu] = 1;
        for(int i=head[pu];~i;i = e[i].next){
            int v = e[i].v;
            int w = e[i].w;
            if(vis[v] == 0 && dis[pu] + w < dis[v]){
                dis[v] = dis[pu] + w;
                que.push((edg){v,dis[v]});
            }
        }
    }
}
int main()
{
    n=read,m=read;
    init();
    memset(head,-1,sizeof head);
    for(int i=1;i<=m;i++){
        int u=read,v=read,w=read;
        add(u,v,w);
        add(n+v,n+u,w);
    }
    ll ans = 0;
    dij(1);
    for(int i=2;i<=n;i++) ans += dis[i];
    init();
    dij(n+1);
    for(int i=1+n;i<=2*n;i++) ans += dis[i];
    cout<<ans;
    return 0;
}


目录
相关文章
|
6月前
|
算法
最短路之Floyd算法
最短路之Floyd算法
74 1
|
6月前
|
算法
最短路之Dijkstra算法
最短路之Dijkstra算法
54 0
|
算法
Floyd算法的应用
Floyd算法的应用
72 0
|
3月前
|
算法
Floyd算法
Floyd算法
43 1
|
6月前
|
算法
Frogger(Floyd算法)
Frogger(Floyd算法)
|
11月前
|
C++
|
11月前
|
机器学习/深度学习 编解码 算法
|
11月前
|
算法
floyd算法
floyd算法
|
算法
Floyd算法(多源最短路径问题)
Floyd算法(多源最短路径问题)
119 0
Floyd算法(多源最短路径问题)
|
机器学习/深度学习 定位技术