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

风格不统一 提交于 2020-03-04 07:32:32

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\n",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\n",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\n",ans);
79     }
80     return 0;
81 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!