1. 程式人生 > >Aizu - 2200 Mr. Rito Post Office

Aizu - 2200 Mr. Rito Post Office

枚舉 bsp one for play show min tdi 順序

題意:/*你是某個島國(ACM-ICPC Japan)上的一個苦逼程序員,
你有一個當郵遞員的好基友利騰桑遇到麻煩了:
全島有一些鎮子通過水路和旱路相連,走水路必須要用船,在X處下船了船就停在X處。
而且島上只有一條船,下次想走水路還是得回到X處才行;
兩個鎮子之間可能有兩條以上的水路或旱路;
郵遞員必須按照清單上的鎮子順序送快遞
(鎮子可能重復,並且對於重復的鎮子不允許一次性處理,比如ABCB的話B一定要按順序走兩次才行)。*/

思路:弗洛伊德求出弗洛伊德求出陸路,水路任意兩點間的最短距離,然後動態規劃求解。

技術分享
#include<iostream>
#include<cstdio>
#include
<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<set> #include<queue> #include<string> #include<algorithm> #define MAXSIZE 1005 #define LL long long #define INF 0x3f3f3f using namespace std; int lmap[MAXSIZE][MAXSIZE],smap[MAXSIZE][MAXSIZE],dp[MAXSIZE][MAXSIZE],q[MAXSIZE],n,m;
int solve() { for(int k=1;k<=n;k++) //弗洛伊德求出陸路,水路任意兩點間的最短距離 { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { lmap[i][j] = min(lmap[i][j],lmap[i][k]+lmap[k][j]); smap[i][j] = min(smap[i][j],smap[i][k]+smap[k][j]); } } } dp[
1][q[1]] = 0; //初始在第一個城市 for(int i=1;i<=m;i++) //現在派送的城市 { for(int j=1;j<=n;j++) //枚舉船在那個城市 { dp[i][j] = min(dp[i][j],dp[i-1][j]+lmap[q[i-1]][q[i]]); for(int k=1;k<=n;k++) //枚舉把船停到那個城市 { dp[i][k] = min(dp[i][k],dp[i-1][j]+lmap[q[i-1]][j]+smap[j][k]+lmap[k][q[i]]); } } } int minn = INF; for(int i=1;i<=n;i++) { if(minn > dp[m][i]) minn = dp[m][i]; } return minn; } void Init() { for(int i=0;i<MAXSIZE;i++) { for(int j=0;j<MAXSIZE;j++) { if(i == j) { //dp[i][j] = 0; lmap[i][j] = 0; smap[i][j] = 0; } else { lmap[i][j] = INF; smap[i][j] = INF; } dp[i][j] = INF; } } } int main() { char op[5]; int u,v,w; while(scanf("%d%d",&n,&m),n+m) { Init(); for(int i=1;i<=m;i++) { scanf("%d%d%d%s",&u,&v,&w,op); if(op[0] == L) { lmap[u][v] = lmap[v][u] = min(lmap[u][v],w); } else { smap[u][v] = smap[v][u] = min(smap[u][v],w); } } scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d",&q[i]); int ans = solve(); printf("%d\n",ans); } return 0; }
View Code

Aizu - 2200 Mr. Rito Post Office