• HDU 2066 一个人的旅行(Dijkstra+Floyd)


    一个人的旅行

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12103    Accepted Submission(s): 4111

    Problem Description
    虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中    会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
     
    Input
    输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;    接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路) 接着的第T+1行有S个数,表示和草儿家相连的城市;    接着的第T+2行有D个数,表示草儿想去地方。
     
    Output
    输出草儿能去某个喜欢的城市的最短时间。
     
    Sample Input
    6 2 3 1 3 5 1 4 7 2 8 12 3 8 4 4 9 12 9 10 2 1 2 8 9 10
     
    Sample Output
    9
     
    Author
    Grass
     
    Source
     
    Recommend
    lcy
     

    PS:表示这题提交了好多次。。。。。一开始用Floyd算法提交超时了,然后各种修改……还是不行,后来又改Dijkstra算法,参考了下discuss那的代码,结果又因为那最大值取小了WA了好几次(题目说a,b<=1000,我就取1001了,惨痛的教训啊)。。。虽然用Dijkstra算法过了,但是自己纳闷了,为啥用Floyd算法就超时了呢?还好discuss那有Floyd算法的代码可以参考下,经过多次TLE之后,总算AC了。。。。艰难的最短路啊

    思路:

    1>Dijkstra算法:因为开始的点有多个,可以构造一个虚拟起点,让所有的起点指向该虚拟起点,即虚拟起点到各起点之间距离为0,同时,构造一个虚拟终点,让所有的终点指向该虚拟终点,之后就可以放心使用Dijkstra算法了

    2>Floyd算法:可以设置两个标志数组,一个设置起点标志为1(或true),一个设置终点标志为1(或true),然后在Floyd算法核心部分加上判断:预设一个变量,只要遍历的点包含起点和终点,就将其与预设变量进行比较,存储最小值,从而得到最短时间。注意此时代码提交会TLE,应在第二重循环部分添加一行:if(g[i][k]!=MAX)(额,变量视自己代码而定吧)

    特别注意:本题有重边。。。。。

     Dijkstra代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define N 1000+2
     5 #define MAX 9999999
     6 using namespace std;
     7 int g[N][N],n,d[N];
     8 void init()
     9 {
    10     int i,j;
    11     for(i=0;i<N;i++)
    12     for(j=0;j<N;j++)
    13     {
    14         if(i==j)g[i][j]=0;
    15         else g[i][j]=MAX;
    16     }
    17 }
    18 void getd(int t,int a,int b)
    19 {
    20     int i,j,temp,max=0,s;
    21     while(t--)
    22     {
    23         scanf("%d %d %d",&i,&j,&temp);
    24         if(g[i][j]>temp)g[i][j]=g[j][i]=temp;
    25         if(i>max)max=i;
    26         if(j>max)max=j;
    27     }
    28     n=++max;
    29     while(a--)
    30     {
    31         scanf("%d",&s);
    32         g[s][0]=g[0][s]=d[s]=0;
    33     }
    34     while(b--)
    35     {
    36         scanf("%d",&s);
    37         g[s][n]=g[n][s]=0;
    38     }
    39 }
    40 int Dijkstra(int s,int t)
    41 {
    42     int i,j,w,minc,mark[N];
    43     for (i=0;i<=n;i++)
    44     { 
    45         if(i==s){mark[s]=1;d[s]=0;}
    46         else
    47         {
    48             d[i]=g[s][i];
    49             mark[i]=0;
    50         } 
    51     }
    52     for (i=1;i<=n;i++)
    53     {
    54         minc=MAX;
    55         w=0;
    56         for (j=1;j<=n;j++)
    57         if (!mark[j]&&minc>d[j]) {minc=d[j];w=j;}
    58         mark[w]=1;
    59         for (j=0;j<=n;j++)
    60         if (!mark[j]&&(g[w][j]<MAX)&&(d[j]>d[w]+g[w][j]))d[j]=d[w]+g[w][j];
    61     }
    62     return d[t];
    63 }
    64 int main()
    65 {
    66     int t,a,b;
    67     while(scanf("%d %d %d",&t,&a,&b)!=EOF)
    68     {
    69         init();
    70         getd(t,a,b);
    71         printf("%d\n",Dijkstra(0,n));
    72     }
    73     return 0;
    74 }

    Floyd代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define N 1010
     5 #define MAX 9999999
     6 using namespace std;
     7 int g[N][N], n, flag1[N], flag2[N];
     8 void init()
     9 {
    10     int i, j;
    11     for(i = 0; i < N; i++)
    12         for(j = 0; j < N; j++)
    13         {
    14             if(i == j)g[i][j] = 0;
    15             else g[i][j] = MAX;
    16         }
    17 }
    18 void getd(int t, int a, int b)
    19 {
    20     int s, i, j, temp;
    21     while(t--)
    22     {
    23         scanf("%d %d %d", &i, &j, &temp);
    24         if(g[i][j] > temp)g[i][j] = g[j][i] = temp;
    25         if(i > n)n = i;
    26         if(j > n)n = j;
    27     }
    28     memset(flag1, 0, sizeof(flag1));
    29     memset(flag2, 0, sizeof(flag2));
    30     while(a--)
    31     {
    32         scanf("%d", &s);
    33         flag1[s] = 1;
    34     }
    35     while(b--)
    36     {
    37         scanf("%d", &s);
    38         flag2[s] = 1;
    39     }
    40 }
    41 void floyd()
    42 {
    43     int i, j, k, temp = MAX;
    44     for(k = 1; k <= n; k++)
    45     {
    46         for(i = 1; i <= n; i++)
    47         {
    48             if(g[i][k] != MAX)
    49                 for(j = 1; j <= n; j++)
    50                 {
    51                     if(g[i][j] > g[i][k] + g[k][j])
    52                         g[i][j] = g[i][k] + g[k][j];
    53                     if(flag1[i] && flag2[j] && g[i][j] < temp)
    54                         temp = g[i][j];
    55                 }
    56         }
    57     }
    58     printf("%d\n", temp);
    59 }
    60 int main()
    61 {
    62     int t, a, b, s, i, j, temp;
    63     while(scanf("%d %d %d", &t, &a, &b) != EOF)
    64     {
    65         init();
    66         getd(t, a, b);
    67         floyd();
    68     }
    69     return 0;
    70 }


     

  • 相关阅读:
    局部加权回归、欠拟合、过拟合(Locally Weighted Linear Regression、Underfitting、Overfitting)
    损失函数(Loss Function)
    线性回归、梯度下降(Linear Regression、Gradient Descent)
    从BSP模型到Apache Hama
    Apache Hama安装部署
    C#中的面向对象编程
    0<Double.MIN_VALUE
    Java方法的参数传递方式为: 值传递
    数据取对数的意义
    UBuntu安装配置记录
  • 原文地址:https://www.cnblogs.com/lfeng/p/2987681.html
Copyright © 2020-2023  润新知