洛谷 P1346 电车 Floyed算法模板

洛谷 P1346 电车 最短路

题解:

首先要进行建图,这是一个有向图,把开口的边的权值设为0,没有开口的边的权值设为1。
因为n比较小,可以用dijkstra,也可以用floyed

代码如下:

(1)Dijkstra O(n2)

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#define MAX 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,s,e;//n为路口数,s,e为起点和终点
int dis[MAX],visit[MAX],mp[MAX][MAX];


void dijkstra(int s){
    dis[s]=0;
    for(int i=0;i<n;i++){
        int u=-1,minl=INF;
        for(int j=1;j<=n;j++){
            if(dis[j]<minl&&visit[j]==0){
                u=j;
                minl=dis[j];
            }
        }
        if(u==-1) return;
        visit[u]=1;
        for(int v=1;v<=n;v++){
            if(visit[v]==0&&mp[u][v]!=INF){
                if(dis[v]>dis[u]+mp[u][v]){
                    dis[v]=dis[u]+mp[u][v];
                }
            }
        }
    }
}

int main(){
    scanf("%d%d%d",&n,&s,&e);
    for(int i=0;i<MAX;i++){
        visit[i]=0;
        dis[i]=INF;
    }
    for(int i=0;i<MAX;i++){
        for(int j=0;j<MAX;j++){
            mp[i][j]=INF;
        }
    }
    int k,a;
    for(int i=1;i<=n;i++){
        scanf("%d",&k);
        for(int j=0;j<k;j++){
            scanf("%d",&a);
            if(j==0) mp[i][a]=0;
            else mp[i][a]=1;
        }
    }
    dijkstra(s);
    if(dis[e]==INF) printf("-1");
    else printf("%d",dis[e]);

    return 0;
}

(2)Floyed 时间复杂度O(n3)

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<queue>
#include<cstring>
#include<vector>
#define MAX 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,s,e,f[MAX][MAX];//f[i][j]表示从i到j的长度
void floyed(){//floyed模板
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(!(i==j||i==k||j==k)){//i不能等于j, j不能等于k, i不能等于k
                    f[i][j]=min(f[i][k]+f[k][j],f[i][j]);//取最小值
                }
            }
        }
    }
}
int main(){
    memset(f, INF, sizeof(f));//初始化f
    scanf("%d%d%d",&n,&s,&e);
    for(int i=1;i<=n;i++){//自己到自己不用按开关
        f[i][i] = 0;
    }
    int k,a;
    for(int i=1;i<=n;i++){
        scanf("%d",&k);
        for(int j=1;j<=k;j++){
            scanf("%d", &a);
            if(j==1){//第一个赋值为0
                f[i][a] = 0;
            }
            else{
                f[i][a] = 1;
            }
        }
    }
    floyed();
    if(f[s][e]==INF){
        printf("-1");
    }
    else{
        printf("%d", f[s][e]);
    }
    return 0;
}
发布了253 篇原创文章 · 获赞 15 · 访问量 7974

猜你喜欢

转载自blog.csdn.net/weixin_44123362/article/details/104028453
今日推荐