申請SAE

如果您發現本博客的外觀很難看,那是因為部分外觀文件被中國.國家.防火.牆屏.蔽所致!
請翻~牆!

我的Wordpress博客的地址: http://zhuyf.tk/

2012年2月12日 星期日

[次短路徑]HAOI2005 路由選擇問題 route 解題報告

路由選擇問題

【問題描述】

    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至少有兩條不同路徑)


【輸入輸出樣例】


route.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

route.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  


【分析】
這題很沒意思啊~想要求次短路就直接問唄,還弄幾個壞節點~

數據規模很小,N<=50,這麼小的數據規模很不符合『省選』的風格啊,這哪怕時亂搞一個O(N^4)的算法也能過~雖然我的是次短路時O(N^2*M)的~

這道題目需要存爲有向圖。

第一問求最短路(需要排除幾個故障節點),把壞掉的節點標記一下,
在單源最短路算法中擴展時跳過就行了~我寫了Dijkstra。
第二問也是求最短路,只不過不考慮故障的頂點,只需要把剛纔標記的節點再去掉標記然後再Dijkstra一下就行了。

第三問是次短路徑,雖然可以用求K短路徑的Yen算法,但是這畢竟時『次』短啊,只需要枚舉最短路徑的每條邊,將它刪去然後求最短路,找出他們的最小的最短路即爲次短路。

【我的代碼】

C++语言: Codee#25474
001 /*
002 * Problem: HAOI2005 路由選擇問題
003 * Author: Yee-fan Zhu
004 * Website: http://zhuyf.tk/
005 * Method: (2nd) Shortest-Path
006 * Algorithm: Dijkstra
007 * Cost: 0.000s
008 * Memory: 472KB
009 */
010 #include <cstdio>
011 #include <cstdlib>
012 #include <cstring>
013 using namespace std;
014 const int INF=100000000;
015 const int MAXN=51;
016 int  Wasu[MAXN];//壞掉的節點
017 int N;//總節點數
018 int P;//壞掉的節點數
019 int S,T;//起訖點
020
021 class Graph
022 {
023 public:
024     int Map[MAXN][MAXN];//臨接矩陣存圖
025     int dist[MAXN];
026     int prev[MAXN];
027     int flag[MAXN];
028     int Node[MAXN];
029     int Top;
030     int ShortestPath()
031     {
032         int ans;
033         for(int i=1;i<=N;i++)
034         {
035             dist[i]=INF;
036             flag[i]=0;
037             prev[i]=0;
038         }
039        
040         for(int i=1;i<=N;i++)
041         {
042             if(Map[S][i]==0 || Wasu[i]==0)
043                 continue;
044             dist[i]=Map[S][i];
045             prev[i]=S;
046         }
047        
048         dist[S]=0;
049         flag[S]=1;
050        
051         for(int i=2;i<=N;i++)
052         {
053             int tmp=INF;
054             int u=S;
055             for(int j=1;j<=N;j++)
056             {
057                 if((!flag[j]) && dist[j]<tmp && Wasu[j]==1)
058                 {
059                     u=j;
060                     tmp=dist[j];
061                 }
062             }
063             flag[u]=1;
064             for(int j=1;j<=N;j++)
065             {
066                 if(flag[j]==1)
067                     continue;
068                 if(Map[u][j]==0)
069                     continue;
070                 if(Wasu[j]==0)
071                     continue;
072                 int newdist=dist[u]+Map[u][j];
073                 if(newdist<dist[j])
074                 {
075                     dist[j]=newdist;
076                     prev[j]=u;
077                 }
078             }
079         }
080         ans=dist[T];
081         return ans;
082     }
083    
084     void GetPath()
085     {
086         Top=1;
087         int p=T;
088         for(int i=1;i<=N;i++)
089             Node[i]=0;
090         while(p!=S)
091         {
092             Node[Top]=p;
093             p=prev[Node[Top]];
094             Top++;
095         }
096         Node[Top]=S;    
097        
098         int tt[MAXN];
099         for(int i=1;i<=Top;i++)
100             tt[i]=Node[Top-i+1];
101         for(int i=1;i<=Top;i++)
102             Node[i]=tt[i];
103     }
104    
105     void NewGraph(Graph *New,int x)
106     {
107         for(int i=1;i<=N;i++)
108             for(int j=1;j<=N;j++)
109                 New->Map[i][j]=Map[i][j];
110         New->Map[Node[x]][Node[x+1]]=0;       
111     }
112 }G,Sec;
113
114 void init()
115 {
116     scanf("%d %d %d\n",&N,&S,&T);
117     for(int i=1;i<=N;i++)
118     {
119         Wasu[i]=1;
120         for(int j=1;j<=N;j++)
121             scanf("%d",&G.Map[i][j]);
122     }
123     scanf("%d",&P);
124     int tmp;
125     for(int i=1;i<=P;i++)
126     {
127         scanf("%d",&tmp);
128         Wasu[tmp]=0;
129     }
130     return;
131 }
132
133 void Solve()
134 {
135     int Ans1=G.ShortestPath();
136     for(int i=1;i<=N;i++) Wasu[i]=1;
137     int Ans2=G.ShortestPath();
138     printf("%d %d ",Ans1,Ans2);
139    
140     G.GetPath();
141    
142     int top=G.Top;
143     /*printf("%d\n",top);*/
144     int Min=INF;
145     int res;
146     for(int i=1;i<top;i++)
147     {
148         G.NewGraph(&Sec,i);
149         res=Sec.ShortestPath();
150         if(res<Min)
151             Min=res;
152     }
153     printf("%d\n",Min);
154 }
155
156 int main()
157 {
158     freopen("route.in","r",stdin);
159     freopen("route.out","w",stdout);
160     init();   
161     Solve();
162     return 0;   
163 }

沒有留言:

張貼留言