ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)

來源:互聯網
上載者:User

標籤:

這是一道非常好的題目,融合了很多知識點。

 

 

 

ZOJ1232-Adventrue of Super Mario

 

  這一題折磨我挺長時間的,不過最後做出來非常開心啊,哇哢哢哢

  題意就不累述了,注釋有寫,痛點在於狀態轉移方程的確立和SPFA的過程

 

  1 //最短路:Floyd+SPFA(BFS)+DP  2 //Time:20Ms    Memory:336K  3 //題目很好,資料較弱,網上部分代碼有些問題卻能夠A掉  4 //題意:超級馬里奧要從A+B處背著公主以最短路程到達1處,其中1-A是村莊,剩下的是城堡  5 //        有可使用K次可飛過L長的靴子(每次都以結點開始或結束),求最短路長  6 //首先需要得到任意兩點之間的最短路-Floyd較為簡便(10^5次操作也能接受)  7 //其次需要利用BFS從A+B處開始遍曆並進行狀態轉移-BFS+DP  8 //構造狀態:DP[i][k]:從i到A+B經過k次瞬移得到的最短路  9 //狀態轉移方程: 10 //能夠從x瞬移到y:dp[x][k] = min(dp[x][k], dp[y][k - 1], dp[y][k] + d[x][y]) 11 //不能從x瞬移到y:dp[x][k] = min(dp[x][k], dp[y][k] + d[x][y]) 12 #include<iostream> 13 #include<cstring> 14 #include<cstdio> 15 #include<algorithm> 16 #include<queue> 17 #include<vector> 18 using namespace std; 19  20 #define INF 0x3f3f3f3f 21 #define MAX 105 22  23 vector<int> e[MAX];    //鄰接表 24 int A, B, M, L, K; 25 int d[MAX][MAX];    //distance 26 bool fly[MAX][MAX];    //能否瞬移 27 int vis[MAX]; 28 int dp[MAX][12];    //dp[i][k]:從i到A+B經過k次瞬移得到的最短路 29  30 void floyd(int N) 31 { 32     for (int i = 1; i <= N; i++) 33         d[i][i] = 0; 34     for (int k = 1; k <= N; k++) 35         for (int i = 1; i <= N; i++) 36             for (int j = 1; j <= N; j++) 37                 if (d[i][j] > d[i][k] + d[k][j]) 38                 { 39                     d[i][j] = d[i][k] + d[k][j]; 40                     if (k <= A && d[i][j] <= L) 41                     { 42                         fly[i][j] = true; 43                         e[i].push_back(j); 44                     } 45                 } 46 } 47  48 int main() 49 { 50     //freopen("in.txt", "r", stdin); 51     //freopen("out-2.txt", "w", stdout); 52     int T; 53     scanf("%d", &T); 54     while (T--) { 55         memset(d, INF, sizeof(d)); 56         memset(fly, false, sizeof(fly)); 57         memset(e, 0, sizeof(e)); 58         scanf("%d%d%d%d%d", &A, &B, &M, &L, &K); 59         while (M--) { 60             int u, v, w; 61             scanf("%d%d%d", &u, &v, &w); 62             d[v][u] = d[u][v] = w; 63             e[v].push_back(u); 64             e[u].push_back(v); 65             if (w <= L)    fly[u][v] = fly[v][u] = true; 66         } 67  68         floyd(A + B); 69         //類似SPFA的過程(BFS) 70         memset(dp, INF, sizeof(dp)); 71         for (int i = 1; i <= K; i++) 72             dp[A + B][i] = 0; 73         for (int i = 1; i <= A + B; i++) 74             dp[i][0] = d[i][A + B]; 75         for (int k = 1; k <= K; k++) 76         { 77             memset(vis, false, sizeof(vis)); 78             queue<int> q; 79             q.push(A + B);    //從A+B開始遍曆 80             vis[A + B] = true; 81             while (!q.empty()) { 82                 int cur = q.front(); 83                 q.pop(); 84                 for (int i = 0; i < e[cur].size(); i++) 85                 { 86                     int u = e[cur][i]; 87                     int tmp = dp[u][k]; 88                     //狀態轉移 89                     if (fly[u][cur])    //可瞬移 90                         dp[u][k] = min(dp[u][k], dp[cur][k - 1]); 91                     dp[u][k] = min(dp[u][k], dp[cur][k] + d[cur][u]); 92                     //需要轉移狀態的條件 - 沒有訪問過 or 最短路長變更 93                     if (!vis[u] || tmp != dp[u][k]) 94                         q.push(u); 95                     vis[u] = true; 96                 } 97             } 98         } 99         printf("%d\n", dp[1][K]);100     }101     return 0;102 }

 

ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.