• 【杭电】[3790]最短路径问题


    这里写图片描述

    双权最短路
    需要同时考虑两个权值
    这里是优先长度,长度相同的情况下优先花费较少的边

    有点麻烦的是
    之前用的写法的逻辑似乎出了点问题
    在更新边长时的判断不够严谨
    好在最后发现了

    还有这种类型的题
    一般都需要考虑重边问题

    用的Dijkstra

    #include<stdio.h>
    int e[1200][1200],q[1200][1200],dis[1200],qs[1200];
    int main() {
        int inf=99999999;
        int n,m;
        while(scanf("%d %d",&n,&m),n||m) {
            for(int i=1; i<=n; i++) {
                for(int j=1; j<=n; j++) {
                    if(i==j)
                        e[i][j]=0;
                    else
                        q[i][j]=e[i][j]=inf;
                }
            }
            while(m--) {
                int x,y,t1,t2;
                scanf("%d %d %d %d",&x,&y,&t1,&t2);
                if(e[x][y]>t1||(e[x][y]==t1&&q[x][y]>t2)) {
                    e[x][y]=e[y][x]=t1;
                    q[x][y]=q[y][x]=t2;
                }
            }
            int s,t;
            scanf("%d %d",&s,&t);
            for(int i=1; i<=n; i++) {
                qs[i]=q[s][i];
                dis[i]=e[s][i];
            }
            bool flag[1200];
            for(int i=1; i<=n; i++)
                flag[i]=false;
            flag[s]=true;
            for(int i=1; i<=n; i++) {
                int min=inf,mmin=inf,tj;
                for(int j=1; j<=n; j++) {
                    if(!flag[j]&&(dis[j]<min||(dis[j]==min&&qs[j]<mmin))) {
                        min=dis[j];
                        mmin=qs[j];
                        tj=j;
                    }
                }
                flag[tj]=true;
                for(int k=1; k<=n; k++) {
                    if(!flag[k]&&(dis[k]>dis[tj]+e[tj][k]||(dis[k]==dis[tj]+e[tj][k]&&qs[k]>qs[tj]+q[tj][k]))) {
                        qs[k]=qs[tj]+q[tj][k];
                        dis[k]=dis[tj]+e[tj][k];
                    }
                }
            }
            printf("%d %d
    ",dis[t],qs[t]);
        }
        return 0;
    }
    

    再放一个Floyd的吧
    不过这个超时了

    #include <stdio.h>
    int e[1200][1200];
    int q[1200][1200];
    int main() {
        int inf=9999999;
        int n,m;
        while(scanf("%d %d",&n,&m),n||m) {
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    if(i==j)
                        e[i][j]=0;
                    else {
                        q[i][j]=e[i][j]=inf;
                    }
            while(m--) {
                int x,y,t1,t2;
                scanf("%d %d %d %d",&x,&y,&t1,&t2);
                if(t1<e[x][y]||(t1==e[x][y]&&q[x][y]>t2)) {
                    e[x][y]=t1;
                    q[x][y]=t2;
                }
            }
            for(int k=1; k<=n; k++)
                for(int i=1; i<=n; i++)
                    for(int j=1; j<=n; j++)
                        if(e[i][j]>e[i][k]+e[k][j]||(e[i][j]==e[i][k]+e[k][j]&&q[i][j]>q[i][k]+q[k][j])) {
                            e[i][j]=e[i][k]+e[k][j];
                            q[i][j]=q[i][k]+q[k][j];
                        }
            int s,t;
            scanf("%d %d",&s,&t);
            printf("%d %d
    ",e[s][t],q[s][t]);
        }
        return 0;
    }

    题目地址:【杭电】[3790]最短路径问题

  • 相关阅读:
    使用本地系统帐户和域用户帐户两者区别(microsoft SQLServer2000)(ZT)
    Winform中消息循环、异步操作、Control.Invoke&Control.BeginInvoke学习
    SQL字符串的分组聚合(ZT)
    一次项目维护案例而对事务学习的笔记
    NOIP2011提高组 选择客栈
    NOIP2012提高组 Day 2 Problem 2 借教室
    201793模拟赛T2 取数(win)
    201793模拟赛T1 卡片(card)
    01Dart 变量常量
    01TypeScript 基础类型
  • 原文地址:https://www.cnblogs.com/BoilTask/p/12569698.html
Copyright © 2020-2023  润新知