(floyd+矩阵快速幂)POJ 3613 - Cow Relays

题意:

给一个无向带权图,求从s到t走k次的最短路。

分析:

一开始没想到,其实应该想到的,看到这种k很大,而且精确k次的题目,第一个一定要考虑快速幂。

而这题就是矩阵快速幂,而乘法的过程不是普通乘法,以为给的邻接矩阵表示的花费,所以只有相加才能计算两次走路的花费。

而最短路就是运用floyd的思想进行“乘法”。

每次乘法求最短路,计算k次,就是矩阵快速幂。

代码:

  1 #include <set>
  2 #include <map>
  3 #include <list>
  4 #include <cmath>
  5 #include <queue>
  6 #include <stack>
  7 #include <vector>
  8 #include <bitset>
  9 #include <string>
 10 #include <cctype>
 11 #include <cstdio>
 12 #include <cstring>
 13 #include <cstdlib>
 14 #include <iostream>
 15 #include <algorithm>
 16 // #include <unordered_map>
 17 
 18 using namespace std;
 19 
 20 typedef long long ll;
 21 typedef unsigned long long ull;
 22 typedef pair<int, int> pii;
 23 typedef pair<ull, ull> puu;
 24 
 25 #define inf (0x3f3f3f3f)
 26 #define lnf (0x3f3f3f3f3f3f3f3f)
 27 #define eps (1e-9)
 28 #define fi first
 29 #define se second
 30 
 31 bool sgn(double a, string select, double b) {
 32     if(select == "==")return fabs(a - b) < eps;
 33     if(select == "!=")return fabs(a - b) > eps;
 34     if(select == "<")return a - b < -eps;
 35     if(select == "<=")return a - b < eps;
 36     if(select == ">")return a - b > eps;
 37     if(select == ">=")return a - b > -eps;
 38 }
 39 
 40 
 41 //--------------------------
 42 
 43 const ll mod = 1000000007;
 44 const int maxn = 100010;
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 int k, m, s, e;
 53 map<int, int> mm;
 54 int cnt = 0;
 55 
 56 
 57 struct Martix {
 58     int maps[210][210];
 59 
 60     Martix operator*(const Martix &m)const {
 61         Martix res;
 62         memset(res.maps, inf, sizeof(res.maps));
 63         for(int i = 0; i < cnt; i++) {
 64             for(int j = 0; j < cnt; j++) {
 65                 for(int k = 0; k < cnt; k++) {
 66                     res.maps[i][j] = min(maps[i][k] + m.maps[k][j], res.maps[i][j]);
 67                 }
 68             }
 69         }
 70         return res;
 71     }
 72 
 73 
 74     Martix operator^(const ll &b)const {
 75         ll num = b;
 76         Martix res;
 77         Martix tmp  = *this;
 78         memset(res.maps, inf, sizeof(res.maps));
 79         for(int i = 0; i < cnt; i++)res.maps[i][i] = 0;
 80         while(num) {
 81             if(num & 1)res = res * tmp;
 82             tmp = tmp * tmp;
 83             num >>= 1;
 84         }
 85         return res;
 86     }
 87 };
 88 
 89 
 90 
 91 
 92 void solve() {
 93     while(~scanf("%d%d%d%d", &k, &m, &s, &e)) {
 94         int w, u, v;
 95         mm.clear();
 96         Martix A;
 97         cnt = 0;
 98         memset(A.maps, inf, sizeof(A.maps));
 99         for(int i = 0; i < m; i++) {
100             scanf("%d%d%d", &w, &u, &v);
101             if(mm.find(u) == mm.end()) {
102                 mm[u] = cnt++;
103             }
104             if(mm.find(v) == mm.end()) {
105                 mm[v] = cnt++;
106             }
107             A.maps[mm[u]][mm[v]] = w;
108             A.maps[mm[v]][mm[u]] = w;
109         }
110 
111         Martix B = A ^ k;
112         // for(int i = 0; i < cnt; i++) {
113         //     for(int j = 0; j < cnt; j++) {
114         //         printf("%d ", B.maps[i][j] );
115         //     }
116         //     puts("");
117         // }
118         printf("%d\n", B.maps[mm[s]][mm[e]]) ;
119     }
120 
121 }
122 
123 int main() {
124 
125 #ifndef ONLINE_JUDGE
126     freopen("1.in", "r", stdin);
127     freopen("1.out", "w", stdout);
128 #endif
129     // iostream::sync_with_stdio(false);
130     solve();
131     return 0;
132 }

 

posted @ 2017-04-04 17:04  tak_fate  阅读(368)  评论(0编辑  收藏  举报