最短路径

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

稍微补充了下 求任意两点间的最短距离

Dijkstra

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define INF 0x3f3f3f3f
 4 int d[101],w[101][101],f[101];
 5 int Dijkstra(int st,int en,int n)
 6 {
 7     int i,j,min,k;
 8     d[st] = 0;
 9     memset(f,0,sizeof(f));
10     for(i = 1 ;i <= n ; i++)
11         if(i!=st)
12             d[i] = INF;
13     for(i = 1 ;i <= n ; i++)
14     {
15         min = INF;
16         for(j = 1 ;j <= n ;j++)
17             if(!f[j]&&min>=d[j])
18                 min = d[k=j];
19         f[k] = 1;
20         for(j = 1; j <= n ; j++)
21             if(d[j]>d[k]+w[k][j])
22                 d[j] = d[k]+w[k][j];
23     }
24     
25     return d[en];
26 }
27 int main()
28 {
29     int i,j, n, m,x,y,z;
30     while(scanf("%d%d", &n,&m)&&n&&m)
31     {
32         memset(w,INF,sizeof(w));
33         for(i = 1 ;i<= m ;i++)
34         {
35             scanf("%d%d%d", &x,&y,&z);
36             if(w[x][y]>z)
37             {
38                 w[x][y] = z;
39                 w[y][x] = z;
40             }
41         }
42         printf("%d\n",Dijkstra(1,n,n));
43 
44     }
45     return 0;
46 }

Floyd

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define INF 0x3f3f3f3f
 4 int w[101][101];
 5 int Floyd(int st,int en,int n)
 6 {
 7     int i, j, k;
 8     for(i = 1 ; i <= n ; i++)
 9         w[i][i] = 0;
10     for(i = 1 ;i <= n ; i++)
11         for(j = 1 ; j <= n ; j++)
12             for(k = 1 ; k <= n ; k++)
13                 if(w[j][k]>w[j][i]+w[i][k])
14                     w[j][k] = w[j][i]+w[i][k];
15     return w[st][en];
16 }
17 int main()
18 {
19     int i,j, n, m,x,y,z;
20     while(scanf("%d%d", &n,&m)&&n&&m)
21     {
22         memset(w,INF,sizeof(w));
23         for(i = 1 ;i<= m ;i++)
24         {
25             scanf("%d%d%d", &x,&y,&z);
26             if(w[x][y]>z)
27             {
28                 w[x][y] = z;
29                 w[y][x] = z;
30             }
31         }
32         printf("%d\n",Floyd(1,n,n));
33     }
34     return 0;
35 }

 Bellman-Ford算法

http://www.wutianqi.com/?p=1912

每次松弛把每条边都更新一下,若n-1次松弛后还能更新,则说明图中有负环,无法得出结果,否则就成功完成。Bellman-ford算法有一个小优化:每次松弛先设一个旗帜flag,初值为FALSE,若有边更新则赋值为TRUE,最终如果还是FALSE则直接成功退出。

http://poj.org/problem?id=3259

 

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<string.h>
 4 #include<queue>
 5 #define INF 0x3f3f3f
 6 using namespace std;
 7 struct node
 8 {
 9     int u,v,t;
10 }q[5000];
11 int dis[501];
12 int bellford(int n,int m)
13 {
14     int i,j;
15     memset(dis,0,sizeof(0));
16     for(i = 1; i <= n ; i++)
17     {
18         int flag = 0;
19         for(j = 1 ; j <= m ; j++)
20         if(dis[q[j].v]>dis[q[j].u]+q[j].t)
21         {
22             dis[q[j].v] = dis[q[j].u]+q[j].t;
23             flag = 1;
24         }
25         if(!flag)
26         break;
27     }
28     for(j = 1; j <= m ; j++)
29     {
30         if(dis[q[j].v]>dis[q[j].u]+q[j].t)
31             return 1;
32     }
33     return 0;
34 }
35 int main()
36 {
37     int i,j,k,n,m,t,w1,o,a,b,c;
38     scanf("%d",&t);
39     while(t--)
40     {
41         scanf("%d%d%d",&n,&m,&w1);
42         o = 0;
43         for(i = 1 ; i <= m ; i++)
44         {
45             scanf("%d%d%d",&a,&b,&c);
46             o++;
47             q[o].u = a;
48             q[o].v = b;
49             q[o].t = c;
50             o++;
51             q[o].u = b;
52             q[o].v = a;
53             q[o].t = c;
54         }
55         for(i = 1 ; i <= w1 ; i++)
56         {
57             scanf("%d%d%d",&a,&b,&c);
58             o++;
59             q[o].u = a;
60             q[o].v = b;
61             q[o].t = -c;
62         }
63        if(bellford(n,o))
64        printf("YES\n");
65        else
66        printf("NO\n");
67     }
68     return 0;
69 }

 

 

 

posted @ 2012-07-18 20:07  _雨  阅读(278)  评论(0编辑  收藏  举报