首页 > 其他分享 >两个人从不同点出发,然后相遇的最短路问题

两个人从不同点出发,然后相遇的最短路问题

时间:2022-11-11 21:24:40浏览次数:71  
标签:now int 短路 相遇 wi st tot2 不同点 dis

Moving Both Hands

//可以选择一个中转点
//也就是先正着走到这个点
//然后再从这个点开始反着走
//但是如果已经开始反着走了,那就只可以反着走图

//正着和反着跑,有点奇妙
//学到了
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf=1e18;
const int M=2e5+5;
using pii=pair<int,int>;

//传的参数太多了,不如写两个
int h1[M],ne1[M],e1[M],w1[M],tot1;
int h2[M],ne2[M],e2[M],w2[M],tot2;

void add1(int from,int to,int wi) {
    e1[++tot1]=to;
    w1[tot1]=wi;
    ne1[tot1]=h1[from];
    h1[from]=tot1;
}

void add2(int from,int to,int wi) {
    e2[++tot2]=to;
    w2[tot2]=wi;
    ne2[tot2]=h2[from];
    h2[from]=tot2;
}

int n,m;
int dis[M][2];
bool vis[M][2];

void dij() {
    for(int i=1;i<=n;i++)
        dis[i][0]=dis[i][1]=inf;
    dis[1][0]=dis[1][1]=0;
    priority_queue<pii,vector<pii>,greater<pii>>q;
    q.push({dis[1][0],1});
    q.push({dis[1][1],-1});
    while(!q.empty()) {
        auto [st,now]=q.top();
        q.pop();
        if(now>0&&vis[now][0]==0) {
            vis[now][0]=1;
            for(int i=h1[now];i;i=ne1[i]) {
                int to=e1[i],wi=w1[i];
                if(dis[to][0]>st+wi) {
                    dis[to][0]=st+wi;
                    q.push({dis[to][0],to});
                }
            }
            for(int i=h2[now];i;i=ne2[i]) {
                int to=e2[i],wi=w2[i];
                if(dis[to][1]>st+wi) {
                    dis[to][1]=st+wi;
                    q.push({dis[to][1],-to});
                }
            }
        }
        if(now<0&&vis[-now][1]==0) {
            now=abs(now);
            vis[now][1]=1;
            for(int i=h2[now];i;i=ne2[i]) {
                int to=e2[i],wi=w2[i];
                if(dis[to][1]>st+wi) {
                    dis[to][1]=st+wi;
                    q.push({dis[to][1],-to});
                }
            }
        }
    }
}
//从某个点开始反水,然后找到那个最小的距离就可以了

signed main() {
    cin>>n>>m;
    while(m--) {
        int u,v,wi;
        cin>>u>>v>>wi;
        add1(u,v,wi);
        add2(v,u,wi);
    }
    dij();
    for(int i=2;i<=n;i++) {
        int ans=min(dis[i][0],dis[i][1]);
        if(ans==inf)cout<<-1<<' ';
        else cout<<ans<<' ';
    }
    return 0;
}

标签:now,int,短路,相遇,wi,st,tot2,不同点,dis
From: https://www.cnblogs.com/basicecho/p/16882039.html

相关文章

  • 最短路径及最低成本算法实现模型
     在vs环境下进行的操作用两种方法分别模拟实现公园导航1.Dijkstra算法按路径长度递增次序来产生最短路径算法;  dist【】距离,path【】前结点  ①初始化......
  • 最短路板子
    floyedO(n^3) f[i][j]=min(f[i][j],f[i][k]+f[k][j]) memset(f,inf,sizeof(f));for(i=1;i<=m;i++)cin>>x>>y>>z,f[x][y]=f[y][x]=z;for......
  • 最短路中对步数有要求的问题
    一般就是走的步数在k步内,或者恰好是k步有边数限制的最短路如果k比较小大体有两种实现方法:Bellman_Ford直接每一次都把能走的边都走一次,一共重复k次#include<bits/st......
  • 864. 获取所有钥匙的最短路径
    864.获取所有钥匙的最短路径题解:bfs总共不超过6把钥匙,通过位运算保存钥匙classSolution{publicintshortestPathAllKeys(String[]grid){in......
  • Leetcode第864题:获取所有钥匙的最短路径(Shortest path to get all keys)
    解题思路想到最短路径问题,自然想到用BFS解决问题,但是只记录位置还不够,还需要记录当前拥有的钥匙状态。需要的数据结构钥匙的个数是\(1-6\),用一个二进制数表示钥匙的状......
  • 同余最短路
    跳楼机题目背景DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧。题目描述Srwudi的家是一幢\(h\)层的摩天大楼。由于前来学习的蒟蒻越来越多,srwudi改造了一......
  • 最短路
    题目:题解:模板题#include<bits/stdc++.h>usingnamespacestd;intpos[105][105];intdis[105];intvis[105];intinf=0x3f3f3f3f;intn,m;voiddij(){memset(dis,inf,si......
  • 最短路问题杂谈
    感觉这类问题好多变形,记录一下,方便复习。P1522[USACO2.4]牛的旅行CowTours由于题目的N很小,且要求任意两点之间距离,很容易想到一下暴力做法:求出题目的联通块,记id[......
  • 朴素的dijkstra最短路径算法
    dijkstra算法适用于无负权图中求最短路径,时间复杂度为O(n^2+e),n为节点数,e为边数需要的数据:1.n行两列数组arr[n][2],第一列记录当前节点到出发点的最短距离,第二列记录当......
  • 算法导论(第24章 单源最短路径)
    目录问题描述最短路径的几个变体最短路径的最优子结构负权重的边环路最短路径的表示松弛操作最短路径和松弛操作的性质本章概要24.1\(Bellman-Ford\)算法24.2有向无环图......