poj 1847 最短路简单题,dijkstra

1、poj  1847  Tram   最短路

2、总结:用dijkstra做的,算出a到其它各个点要改向的次数。其它应该也可以。

题意: 有点难懂。n个结点,每个点可通向ki个相邻点,默认指向第一个相邻点,可以改变指向。求一条从A到B的路,使用最少改变路上点的指向的次数。

#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstdio>
#define max(a,b) a>b?a:b
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
const int N=110;

int mapn[N][N],visit[N];
int change[N];  //改向的次数
int n,a,b;

void Dijkstra()
{
    int f;
    memset(visit,0,sizeof(visit));
    for(int i=1;i<=n;i++){
        change[i]=mapn[a][i];
    }
    visit[a]=1;

    for(int i=2;i<=n;i++)
    {
        int minn=INF;
        f=-1;
        for(int j=1;j<=n;j++){
            if(!visit[j]&&minn>change[j]){
                minn=change[j];
                f=j;    //f存储连通分量中到a需改向数最少的点
            }
        }
        if(f==-1)break;    //找不到可通点就跳出
        visit[f]=1;

        for(int j=1;j<=n;j++){  //更新change
            if(!visit[j]&&change[f]+mapn[f][j]<change[j]){
                change[j]=change[f]+mapn[f][j];
            }
        }
    }

    if(change[b]==INF)printf("-1
");
    else printf("%d
",change[b]);
}

int main()
{
    while(scanf("%d%d%d",&n,&a,&b)!=EOF)
    {
        memset(mapn,INF,sizeof(mapn));
        for(int l=1;l<=n;l++)
        {
            int ki,m;
            scanf("%d",&ki);
            if(!ki)continue;  //注意细节
            scanf("%d",&m);
            mapn[l][m]=0;
            for(int i=2;i<=ki;i++){
                scanf("%d",&m);
                mapn[l][m]=1;
            }
        }

        Dijkstra();
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/sbfhy/p/5836109.html