• hdu 2066 ( 最短路) Floyd & Dijkstra & Spfa


    http://acm.hdu.edu.cn/showproblem.php?pid=2066

    今天复习了一下最短路和最小生成树,发现居然闹了个大笑话-----我居然一直写的是Floyd,但我自己一直以为这是Dijkstra---我居然一直把两个算法

    记的是混的,还居然一直没有被别人发现,真是个大乌龙

    好了,看看这道题,赤裸裸的最短路水题,首先来个Floyd的,把城市看成点,将连通的的点赋值为给定的时间,未连通的赋值为很大,这是个无向的关系

    然后就是三个循环,以一个点为媒介,把每个点遍历一遍,比较找出点连通的最小值就行,稍微优化一点点就不会超时了

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define inf 1000000005
     4 using namespace std;
     5 int mp[1001][1001],q[1001];
     6 void jjc()
     7 {
     8     int i,j;
     9     for (i=1;i<=1000;i++){
    10        for (j=1;j<=1000;j++){
    11            if (i==j) mp[i][j]=0;
    12            else mp[i][j]=inf;
    13        }
    14     }
    15 }
    16 int min(int x,int y){
    17     if (x<y) return x;
    18     else return y;
    19 }
    20 int main()
    21 {
    22     int t,s,d,c,i,j,k,w,mx,a,b,mn;
    23     while (~scanf("%d %d %d",&t,&s,&d))
    24     {
    25         jjc();
    26         mx=0;mn=inf;
    27         while (t--)
    28         {
    29             scanf("%d %d %d",&a,&b,&c);
    30             if (mp[a][b]>c)
    31                  mp[a][b]=mp[b][a]=c;
    32             if (a>mx) mx=a;  没有给定范围,所以找范围
    33             if (b>mx) mx=b;
    34             if (a<mn) mn=a;
    35             if (b<mn) mn=b;
    36         }
    37         for (k=mn;k<=mx;k++){
    38             for (i=mn;i<=mx;i++){
    39                 if (mp[i][k]>=inf) continue; //稍微优化一点点
    40                for (j=mn;j<=mx;j++){
    41                    mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
    42                }
    43             }
    44         }
    45         for (i=1;i<=s;i++)
    46           scanf("%d",&q[i]);
    47         int ans=inf;
    48         while (d--)
    49         {
    50             scanf("%d",&w);
    51             for (i=1;i<=s;i++)
    52             {
    53                if (mp[q[i]][w]<ans)
    54                    ans=mp[q[i]][w];
    55             }
    56         }
    57         printf("%d
    ",ans);
    58     }
    59     return 0;
    60 }

    然后是Dijkstra的, Floyd是把任意两点的最短距离都求了出来,而Dijkstra只是求了特定的起点与所有点之间的最短路,一般情况而言,后者要快于前者,具体用哪种根据题目而定

    按照距离从小到大的顺序,找出从给定起点能够到达的下一点,每找到一个这样的点,然后更新其余点之间的距离

    code

     1 #include<cstdio>
     2 #define inf 100000005
     3 using namespace std;
     4 int map[1001][1001],vis[1001],dis[1001];
     5 int st[1001],sr[1001];
     6 int mn,mx;
     7 int min(int x,int y)
     8 {
     9     if (x<y) return x;
    10     else return y;
    11 }
    12 void jjc()
    13 {
    14     int i,j;
    15     for (i=1;i<=1000;i++){
    16         for (j=1;j<=1000;j++){
    17             if (i==j) map[i][j]=0;
    18             else map[i][j]=inf;
    19         }
    20     }
    21 }
    22 void dijkstra(int x)
    23 {
    24     int i,pos,j,q;
    25     for (i=mn;i<=mx;i++)
    26     {
    27         dis[i]=map[x][i];
    28         vis[i]=0;
    29     }
    30     vis[x]=1;
    31     for (i=mn;i<=mx;i++)
    32     {
    33         q=inf;pos=x;
    34         for (j=mn;j<=mx;j++)
    35             if (!vis[j]&&dis[j]<q)
    36             {
    37                 pos=j;
    38                 q=dis[j];
    39             }
    40         vis[pos]=1;
    41         for (j=mn;j<=mx;j++)
    42              dis[j]=min(dis[j],dis[pos]+map[pos][j]);
    43     }
    44 }
    45 int main()
    46 {
    47     int t,s,d,a,b,c,i,j;
    48     while (~scanf("%d %d %d",&t,&s,&d))
    49     {
    50         jjc();
    51         mx=0,mn=inf;
    52         while (t--)
    53         {
    54             scanf("%d %d %d",&a,&b,&c);
    55             if (map[a][b]>c)
    56                map[a][b]=map[b][a]=c;
    57             if (a>mx) mx=a;
    58             if (b>mx) mx=b;
    59             if (a<mn) mn=a;
    60             if (b<mn) mn=b;
    61         }
    62         for (i=1;i<=s;i++)
    63            scanf("%d",&st[i]);
    64         for (i=1;i<=d;i++)
    65             scanf("%d",&sr[i]);
    66         int ans=inf;
    67         for (i=1;i<=s;i++)
    68         {
    69             dijkstra(st[i]);
    70             for (j=1;j<=d;j++)
    71                if (dis[sr[j]]<ans)
    72                   ans=dis[sr[j]];
    73         }
    74         printf("%d
    ",ans);
    75     }
    76     return 0;
    77 }

    队列储存,广搜版的spfa

    code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #define inf 0x3fffffff
     5 using namespace std;
     6 int map[1001][1001],vis[1001],dis[1001];
     7 int st[1001],sr[1001];
     8 int mn,mx,s,d;
     9 void jjc()
    10 {
    11     int i,j;
    12     for (i=1;i<=1000;i++){
    13         for (j=1;j<=1000;j++){
    14             if (i==j) map[i][j]=0;
    15             else map[i][j]=inf;
    16         }
    17     }
    18 }
    19 int spfa()
    20 {
    21    int num,i;
    22    memset(vis,0,sizeof(vis));
    23    for (i=mn;i<=mx;i++)
    24        dis[i]=inf;
    25    queue<int> q;
    26    for (i=1;i<=s;i++)
    27    {
    28        dis[st[i]]=0;
    29        q.push(st[i]);
    30    }
    31    while(!q.empty())
    32    {
    33        num=q.front();
    34        q.pop();
    35        vis[num]=0;
    36        for (i=mn;i<=mx;i++)
    37        {
    38            if (dis[i]>dis[num]+map[num][i])
    39            {
    40                dis[i]=dis[num]+map[num][i];
    41                if (vis[i]==0)
    42                {
    43                    vis[i]=1;
    44                    q.push(i);
    45                }
    46            }
    47        }
    48    }
    49    int p=inf;
    50    for (i=1;i<=d;i++)
    51    {
    52        if (p>dis[sr[i]]) p=dis[sr[i]];
    53    }
    54    return p;
    55 }
    56 int main()
    57 {
    58     int t,a,b,c,i,j;
    59     while (~scanf("%d %d %d",&t,&s,&d))
    60     {
    61         jjc();
    62         mx=0,mn=inf;
    63         while (t--)
    64         {
    65             scanf("%d %d %d",&a,&b,&c);
    66             if (map[a][b]>c)
    67                map[a][b]=map[b][a]=c;
    68             if (a>mx) mx=a;
    69             if (b>mx) mx=b;
    70             if (a<mn) mn=a;
    71             if (b<mn) mn=b;
    72         }
    73         for (i=1;i<=s;i++)
    74            scanf("%d",&st[i]);
    75         for (i=1;i<=d;i++)
    76             scanf("%d",&sr[i]);
    77         int ans=spfa();
    78         printf("%d
    ",ans);
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    Python的logging模块
    Python中的json模块
    Python的re模块
    NoSQL简介
    单例设计模式
    基于配置文件的方式配置AOP
    重用切点表达式
    切面优先级
    返回通知、异常通知、环绕通知
    后置通知
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/4750493.html
Copyright © 2020-2023  润新知