uva10806Dijkstra?Dijkstra?

每天刷6题的目标看来还是有点难啊~先找一道以前A掉的题目充数吧~不过个人觉得这题用SPFA真的不错的~(因为网络流我还不会o(╯□╰)o)

题意:有A,B两个人要越狱,A成功地从监狱到达火车站时B立即出发,两个人的路线不能有重合(可以重合点,不可以重合边),需要两个人路径和最短,求最短路径和。
抽象一点,就是找到从点S到T的最短长度的环(即:两次路径不能有重边)

思路:最大流的方法可以做,我用的是两次SPFA,相当于求两次最短路:先求一次最短路,然后把最短路上的S->T方向的边长赋值为INF,反向边长赋值为-map[u][v],即原来长度的相反数,然后再次SPFA,两次结果相加即可。
对于标记为反向长度取反,如果不懂,请看下图:
UVA10806 <wbr>用SPFA

代码:

View Code
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <queue>
 5 using namespace std;
 6 const int MAXN = 100 + 5;
 7 const int INF = 0x3f3f3f3f;
 8 #define DEBUG
 9 int map[MAXN][MAXN];
10 int vis[MAXN], d[MAXN], fa[MAXN];
11 void init(int n){
12     int i, j;
13     for(i=1; i<=n; i++)
14         for(j=1; j<=n; j++)
15             if(i!=j) map[i][j]=INF;
16             else map[i][j]=0;
17 }
18 int SPFA(int S, int T, int n){
19     int i;
20     memset(vis, 0, sizeof(vis));
21     memset(d, 63, sizeof(d));
22     d[S] = 0;
23     queue<int>q;
24     q.push(S);
25     vis[S]=1;
26     while(!q.empty()){
27         int x=q.front();
28         q.pop();
29         vis[x]=0;
30         for(i=1; i<=n; i++)
31             if(d[i]>d[x]+map[x][i]){
32                 d[i]=d[x]+map[x][i];
33                 fa[i]=x;
34                 if(!vis[i]){
35                     vis[i]=1;
36                     q.push(i);
37                 }
38             }
39     }
40     return d[T];
41 }
42 int main(){
43 #ifndef DEBUG
44     freopen("in.txt", "r", stdin);
45 #endif
46     int n, m;
47     while(scanf("%d", &n)!=EOF && n){
48         scanf("%d", &m);
49         init(n);
50         int i, u, v, w;
51         for(i=1; i<=m; i++){
52             scanf("%d%d%d", &u, &v, &w);
53             if(map[u][v]>w) map[u][v]=map[v][u]=w;
54         }
55         int S=1, T=n;
56         int ans1 = SPFA(S, T, n);
57         while(T!=S){
58             map[T][fa[T]]=-map[T][fa[T]];
59             map[fa[T]][T]=INF;
60             T=fa[T];
61         }
62         T=n;
63         int ans2=SPFA(S, T, n);
64         if(ans1>=INF||ans2>=INF) printf("Back to jail\n");
65         else printf("%d\n", ans1+ans2);
66     }
67     return 0;
68 }

 

posted @ 2013-02-14 16:27  ChrisZZ  阅读(298)  评论(0编辑  收藏  举报