HAOI2005 路由选择问题

HAOI2005 路由选择问题

第一二个问是标准的最短路经没什么好说,直接用Dijkstra或SPFA即可。只要是第三个问,求次短路。

简单的求次短路方法和求次小生成树基本一样,也是枚举删除一条最短路上的边,在求最短路,再从求出

的值中找出最小的即可。


次短路还有一些扩展可以查看byvoid大牛的blog。


  1  /*
  2   * Problem: HAOI 2005 路由选择问题
  3   * Author: Xu Fei
  4   * Time: 2010.8.2 13.59
  5   * Method: Dijkstra  次短路
  6    */
  7   
  8  #include < iostream >
  9  #include < cstdio >
 10  #include < cstring >
 11  using   namespace  std;
 12 
 13  const   int  MaxN = 55 ,INF = 0xFFFFFFF ;
 14 
 15  struct  Node{
 16       int  x,y;
 17  }Path[MaxN];
 18 
 19  int  N,S,T,Lp,Len;
 20  int  S0,S1,S2;
 21  int  P[MaxN];
 22  int  dis[MaxN];
 23  bool  vis[MaxN];
 24  int  pre[MaxN];
 25  int  temp[MaxN][MaxN];
 26  int  cost[MaxN][MaxN];
 27 
 28  void  into()
 29  {
 30       int  i,j;
 31      
 32      scanf( " %d%d%d " , & N, & S, & T);
 33       for (i = 1 ;i <= N; ++ i)
 34      {
 35           for (j = 1 ;j <= N; ++ j)
 36          {
 37              scanf( " %d " , & cost[i][j]);
 38               if (cost[i][j] == 0 )
 39                  cost[i][j] = INF;
 40          }
 41      }
 42      scanf( " %d " , & Lp);
 43       for (i = 1 ;i <= Lp; ++ i)
 44          scanf( " %d " ,P + i);
 45  }
 46  void  change( bool  flag)
 47  {
 48       int  i,j;
 49      
 50       if (flag)
 51      {
 52          memcpy(temp,cost, sizeof (cost));
 53           for (i = 1 ;i <= Lp; ++ i)
 54               for (j = 1 ;j <= N; ++ j)
 55                  cost[P[i]][j] = INF;
 56      }
 57       else
 58      {
 59          memcpy(cost,temp, sizeof (cost));
 60      }
 61  }
 62  int  dijkstra()
 63  {
 64       int  i,j,Min,kj;
 65      
 66       for (i = 1 ;i <= N; ++ i)
 67      {
 68          dis[i] = cost[S][i];
 69          vis[i] = true ;
 70          pre[i] = S;
 71      }
 72      dis[S] = 0 ;
 73      vis[S] = false ;
 74       for (i = 1 ;i < N; ++ i)
 75      {
 76          Min = INF;
 77           for (j = 1 ;j <= N; ++ j)
 78               if (vis[j] && dis[j] < Min)
 79                  Min = dis[j],kj = j;
 80           if (kj == T)  break ;
 81          vis[kj] = false ;
 82           for (j = 1 ;j <= N; ++ j)
 83               if (vis[j] && dis[j] > dis[kj] + cost[kj][j])
 84              {
 85                  dis[j] = dis[kj] + cost[kj][j];
 86                  pre[j] = kj;
 87              }
 88      }
 89       return  dis[T];
 90  }
 91  void  solve()
 92  {
 93       int  i,tmp,Min;
 94      
 95      change( true );
 96      S0 = dijkstra();
 97      change( false );
 98      S1 = dijkstra();
 99      Len = 0 ;
100      i = T;
101       while (i != S)
102      {
103          Len ++ ;
104          Path[Len].x = pre[i];
105          Path[Len].y = i;
106          i = pre[i];
107      }
108      S2 = INF;
109       for (i = 1 ;i <= Len; ++ i)
110      {
111          tmp = cost[Path[i].x][Path[i].y];
112          cost[Path[i].x][Path[i].y] = INF;
113          cost[Path[i].y][Path[i].x] = INF;
114          Min = dijkstra();
115          cost[Path[i].x][Path[i].y] = tmp;
116          cost[Path[i].y][Path[i].x] = tmp;
117           if (S2 > Min)
118              S2 = Min;
119      }
120      printf( " %d %d %d\n " ,S0,S1,S2);
121  }
122  int  main()
123  {
124      freopen( " t.in " , " r " ,stdin);
125      freopen( " t.out " , " w " ,stdout);
126      
127      into();
128      solve();
129       return   0 ;
130  }

 


路由选择问题(T1)

【问题描述】

    X城有一个含有N个节点的通信网络,在通信中,我们往往关心信息从一个节点I传输到节点J的最短路径。遗憾的是,由于种种原因,线路中总有一些节点会出故障,因此在传输中要避开故障节点。
任务一:在己知故障节点的情况下,求避开这些故障节点,从节点I到节点J的最短路径S0。
任务二:在不考虑故障节点的情况下,求从节点I到节点J的最短路径S1、第二最短路径S2。

【输入文件】

第1行: N I J (节点个数 起始节点 目标节点)
第2—N+1行: Sk1 Sk2…SkN (节点K到节点J的距离为SkJ K=1,2,……,N)
最后一行: P T1 T2……Tp (故障节点的个数及编号)

【输出文件】

S0 S1 S2 (S1<=S2 从节点I到节点J至少有两条不同路径)

t1.in

5 1 5
0 10 5 0 0
10 0 0 6 20
5 0 0 30 35
0 6 30 0 6
0 20 35 6 0
1 2

t2.out

40 22 30

【约束条件】

(1)N<=50 N个节点的编号为1,2,…,N
(2)Skj为整数,Skj<=100,(K,J=1,2…,N 若Skj=0表示节点K到节点J没线路)
(3)P<=5


你可能感兴趣的:(HAOI2005 路由选择问题)