POJ-1847-Tram(裸迪杰斯特拉或弗洛伊德)

R - 基础最短路
Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

POJ 1847
Description
Tram network in Zagreb consists of a number of intersections and rails connecting some of them. In every intersection there is a switch pointing to the one of the rails going out of the intersection. When the tram enters the intersection it can leave only in the direction the switch is pointing. If the driver wants to go some other way, he/she has to manually change the switch.

When a driver has do drive from intersection A to the intersection B he/she tries to choose the route that will minimize the number of times he/she will have to change the switches manually.

Write a program that will calculate the minimal number of switch changes necessary to travel from intersection A to intersection B.
Input
The first line of the input contains integers N, A and B, separated by a single blank character, 2 <= N <= 100, 1 <= A, B <= N, N is the number of intersections in the network, and intersections are numbered from 1 to N.

Each of the following N lines contain a sequence of integers separated by a single blank character. First number in the i-th line, Ki (0 <= Ki <= N-1), represents the number of rails going out of the i-th intersection. Next Ki numbers represents the intersections directly connected to the i-th intersection.Switch in the i-th intersection is initially pointing in the direction of the first intersection listed.
Output
The first and only line of the output should contain the target minimal number. If there is no route from A to B the line should contain the integer “-1”.
Sample Input
3 2 1
2 2 3
2 3 1
2 1 2
Sample Output
0

题意:第一行给出N,A,B,代表有N个点。接下来N行,每行第一个数字为K,随后给出K个数字,i到第一个数字的权值为0,接着i到后面K-1的数字的权值为1。输出A到B的最短路,如果没有就输出-1;

弗洛伊德代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int INF=99999999;
const int maxn=105;//先来弗洛伊德
int map[maxn][maxn];//首先尝试邻接矩阵
int N;//图有N个结点
int A,B;//求A到B的最短路
int K;//每行后面有K个数字
void init_map()//初始化邻接矩阵并存图
{
    for(int i=0; i<=N; i++) //模版初始化图
        for(int j=0; j<=N; j++)
            i==j?map[i][j]=0:map[i][j]=INF;
    for(int i=1; i<=N; i++) //自定义建图
    {
        scanf("%d",&K);//一行K个数
        for(int j=0; j<K; j++)
        {
            int u;//临时接收数据
            scanf("%d",&u);
            j==0?map[i][u]=0:map[i][u]=1;
        }
    }
}
void Floyd()
{
    for(int k=1; k<=N; k++)
        for(int i=1; i<=N; i++)
            for(int j=1; j<=N; j++)
                if(map[i][k]<INF&&map[k][j]<INF&&map[i][j]>map[i][k]+map[k][j])
                    map[i][j]=map[i][k]+map[k][j];
}
int main()
{
    scanf("%d%d%d",&N,&A,&B);
    init_map();
    Floyd();
    map[A][B]==INF?printf("-1\n"):printf("%d\n",map[A][B]);
    return 0;
}

迪杰斯特拉代码


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=105;//先来弗洛伊德
int map[maxn][maxn];//首先尝试邻接矩阵
int dis[maxn];//记录某点到所有点的最短路
bool vis[maxn];//已访问标记为1,初始化为0
//以下为自定义
int N;//图有N个结点
int A,B;//求A到B的最短路
int K;//每行后面有K个数字
void init_map()//初始化邻接矩阵并存图
{
    for(int i=0; i<=N; i++) //模版初始化图
        for(int j=0; j<=N; j++)
            i==j?map[i][j]=0:map[i][j]=INF;
    for(int i=1; i<=N; i++) //自定义建图
    {
        scanf("%d",&K);//一行K个数
        for(int j=0; j<K; j++)
        {
            int u;//临时接收数据
            scanf("%d",&u);
            j==0?map[i][u]=0:map[i][u]=1;
        }
    }
}
void Dijkstra(int point)//dis存储point到各点最短路
{
    for(int i=0; i<=N; i++)
        dis[i]=map[point][i];//初始化dis
    memset(vis,0,sizeof(vis));//初始化为未访问
    vis[point]=1;//标记为已访问
    for(int i=1; i<N; i++) //松弛N-1次
    {
        int minn=INF;//寻找最小值
        int u;//记录最小值下标
        for(int j=1; j<=N; j++)
        {
            if(vis[j]==0&&dis[j]<minn)
            {
                minn=dis[j];
                u=j;
            }
        }
        vis[u]=1;//标记为已访问
// if(minn==INF)//小优化,视情况采用
// break;
        for(int v=1; v<=N; v++)
            if(vis[v]==0&&map[u][v]<INF&&dis[v]>dis[u]+map[u][v])//未松弛过,且两点间有路,且可被松弛
                dis[v]=dis[u]+map[u][v];//松弛
    }
}
int main()
{
    scanf("%d%d%d",&N,&A,&B);
    init_map();
    Dijkstra(A);
    dis[B]<INF?printf("%d\n",dis[B]):printf("-1\n");
    return 0;
}

你可能感兴趣的:(迪杰斯特拉,弗洛伊德)