最短路径 | 1030 两重标尺下的最短路径

只要心里有斯杰斯特拉,多少重标尺都是浮云。

可以看到,进行多重标尺判断的时候,可以用

if(dist[u]+g_dist[u][i]<dist[i] || (dist[u]+g_dist[u][i]==dist[i] && cost[u]+g_cost[u][i]<cost[i])){

这样的骚代码来进行二重标尺的判断。但是如果要记录最短路径条数或者其他骚操作,就不能这么简洁了。

完整代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 1010
#define MAX (1<<30)-1
#define V vector<int>

using namespace std;

int g_dist[LEN][LEN];
int g_cost[LEN][LEN];
int vis[LEN];
int dist[LEN];
int cost[LEN];
int pre[LEN];

int main(){
//    freopen("1030.txt","r",stdin);
    int n,m,s,e,i,j,a,b,c,d,t;
    I("%d%d%d%d",&n,&m,&s,&e);
    fill(g_dist[0],g_dist[0]+LEN*LEN,MAX);
    FF(i,m){
        I("%d%d%d%d",&a,&b,&c,&d);
        g_dist[a][b]=c;
        g_dist[b][a]=c;
        g_cost[a][b]=d;
        g_cost[b][a]=d;
    }
    fill(dist,dist+LEN,MAX);
    fill(cost,cost+LEN,MAX);
    dist[s]=0;
    cost[s]=0;
    pre[s]=-1;
    while(1){
        int u=-1,d=MAX;
        FF(i,n) if(!vis[i] && dist[i]<d){
            u=i;
            d=dist[i];
        }
        if(u<0) break;
        vis[u]=1;
        FF(i,n) if(!vis[i]){
            if(dist[u]+g_dist[u][i]<dist[i] || (dist[u]+g_dist[u][i]==dist[i] && cost[u]+g_cost[u][i]<cost[i])){
                dist[i]=dist[u]+g_dist[u][i];
                cost[i]=cost[u]+g_cost[u][i];
                pre[i]=u;
            }
        }
    }
    vector<int> path;
    i=e;
    while(i!=-1){
        path.insert(path.begin(),i);
        i=pre[i];
    }
    FF(i,path.size()) O("%d ",path[i]);
    printf("%d %d
",dist[e],cost[e]) ;
    return 0;
}
原文地址:https://www.cnblogs.com/TQCAI/p/8524836.html