最短路模板题

· · 题解

题意简述:

解题思路:

  1. 由最小权值我们可以很自然的想到最短路。

  2. 由于本题没有负权值,以我们可以想到使用 Dijkstra 算法(一种基于贪心的算法。

  3. 如果不会 Dijkstra 算法请往下拉或左转 P4779 【模板】单源最短路径(标准版)。

  4. 将从一个单词想起另一个单词的最短时间时间看作从一个点到另一个的最短。

  5. 做完最短路后如果目标点仍是初值的话则代表走不到。

  6. 时间大约为 O(q \cdot n \log n)

注意事项:

代码奉上

#include <bits/stdc++.h>
#define int long long
//本蒟蒻的码风不太好看QWQ 
//蒟蒻的第一篇题解,审核大大求过QWQ
//如果空格又少了审核大大请说一下是哪里(实在找不到了。。QWQ)
using namespace std ;
const int N = 1005 ;
int ans[N] ;
int qu,n,m,bh,zhi ;
string a,b ;
struct ww{
    int id,w ;
    bool operator < (const ww &A) const {return w > A.w;}  //优先队列按权值由小到大排序 
}o; 
vector<ww>bian[N] ;
map<string ,int >p ;
priority_queue<ww>q ;
inline int read(){
    register int x = 0 , f = 1 ;
    register 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;
}//快读 
inline void write(int x){
    if( x < 0 )putchar('-'),x = -x ;
    if( x > 9 )write(x/10) ;
    putchar( x%10+'0' ) ;
}//快写 
void find(){
    while(!q.empty()){
        ww now = q.top() ;//取队首
        if(ans[now.id] != now.w){
            q.pop() ;
            continue ;//走过的排除 
        }
        for(int i = 0 ; i < bian[now.id].size() ; i++ )
            if(ans[now.id]+bian[now.id][i].w<ans[bian[now.id][i].id])
            ans[bian[now.id][i].id] = ans[now.id]+bian[now.id][i].w ,
            o.id = bian[now.id][i].id , o.w = ans[bian[now.id][i].id],
            q.push(o) ;//添加新点 
        q.pop() ;//弹出队首 
    }
}
main(){
//  freopen("alias.in","r",stdin) ;
//  freopen("alias.out","w",stdout) ;
    n = read() , m = read() ;
    for(int i = 1 ; i <= m ; ++i ){
        cin>>a>>b ,zhi = read() ;
        if(p[a]==0)p[a] = ++bh ;
        if(p[b]==0)p[b] = ++bh ;//为新的字符串上编号 
        o.id =p[b] , o.w = zhi ;
         bian[p[a]].push_back(o) ;//存图 
    }
    qu = read() ;
    for(int i = 1 ; i <= qu ; i++ ){
        memset(ans,0x3f,sizeof(ans)) ;//将初始答案赋值为无限大 
        cin>>a>>b ;
        o.id = p[a],o.w = 0 ;//队列的原点 
        q.push(o) ;
        ans[p[a]] = 0 ;
        find() ;
        if(ans[p[b]]>=4557430888798830399)printf("Roger\n") ;//初值为0x3f 
        else write(ans[p[b]]),printf("\n") ;
    } 
    return 0 ;
}