1706: [usaco2007 Nov] relays cool run time limit: 5 sec memory limit: 64 MB
Submit: 346 solved: 166
[Submit] [Status] Description
FJ's N (2 <= n <= 1,000,000) cows chose to run through the relays as their daily exercise program. As for the relay, the current T (2 <= T <= 100) runway in the farm. The runway on the farm has some intersections, and each runway is linked to two different intersections, iyuni and i2_ I (1 <= iyuni <= 1,000; 1 <= i2_ I <= 1,000 ). Each intersection is the endpoint of at least two runways. The cows know the length of each runway length_ I (1 <= length_ I <= 1,000) and the number of the intersection point connecting each runway, no two intersections are directly connected by two different runways. You can think that these intersections and runways form a picture. To complete a relay, all native cows must stand at a certain meeting point before the start of running (some meeting points may stand at more than one cow ). Of course, their positions should ensure that they can pass the baton sequentially, And the cows holding the baton will stop at the preset destination. Your task is to write a program to calculate the minimum possible total length of the running path of the cows when the start point (s) and end point (e) of the relay run are determined. Obviously, this path must exactly pass through N runways.
Input
* Row 1st: Four integers separated by spaces: N, T, S, and E
* Line 2nd. t + 1: I + 1 is a space-separated INTEGER (length_ I, i1_ I, and i2_ I) that describes runway I.
Output
* Row 1st: Output a positive integer, indicating the minimum length of the path that exactly passes through N runways when the start point is s and the end point is E.
Sample input2 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9
Sample output10
Download the data here.
Question:
Given a undirected Weighted Graph of m edges, find the shortest path from the starting point S to the ending point e that exactly passes through K edges. 2 ≤ m ≤ 100, 2 ≤ k ≤ 1000000. Make sure that the vertices of each edge are at least 2.
Practice:
Because the question requires the length (rather than the number of paths) of the shortest path passing through K edges, traditional matrix multiplication cannot be used. First, matrix multiplication is based on the following recursive formula:
\ [F _ {I, j} = F _ {I, k} \ times F _ {k, j} \]
The question is:
\ [G _ {I, j }=\ min (G _ {I, k} + G _ {k, j}) \]
Think about it! Matrix Multiplication can also be used like this!
Great.
1 #include <cstring> 2 #include <cstdio> 3 const int maxn = 100 + 3; 4 const long long INF = 0x3f3f3f3f3f3f3f3f; 5 inline long long min(long long a, long long b) { 6 return a < b ? a : b; 7 } 8 namespace my_matrix { 9 typedef long long MType;10 typedef int IType;11 const MType size = maxn;12 struct Matrix {13 MType d[size][size];14 int row, col;15 inline Matrix() {16 memset(d, 0, sizeof d);17 }18 inline Matrix(int _row, int _col) {19 row = _row, col = _col;20 memset(d, 0, sizeof d);21 }22 inline void init() {23 for(int i = 0; i < row; ++i) {24 d[i][i] = 1;25 }26 }27 inline void set_size(int _set_size) {28 row = col = _set_size;29 }30 inline void clear() {31 memset(d, 0, sizeof d);32 }33 inline void print() {34 for(int i = 0; i < row; ++i) {35 for(int j = 0; j < col - 1; ++j) {36 printf("%lld ", d[i][j]);37 }38 printf("%lld\n", d[i][col - 1]);39 }40 }41 };42 inline Matrix operator * (const Matrix &lhs, const Matrix &rhs) {43 Matrix ret;44 ret.set_size(lhs.row);45 for(int i = 0; i < ret.row; ++i)46 for(int j = 0; j < ret.col; ++j)47 ret.d[i][j] = INF;48 for(int i = 0; i < lhs.row; ++i)49 for(int j = 0; j < rhs.col; ++j)50 for(int k = 0; k < lhs.col; ++k) {51 ret.d[i][j] = min(ret.d[i][j], lhs.d[i][k] + rhs.d[k][j]);52 }53 return ret;54 }55 inline Matrix fast_pow(Matrix base, IType index) {56 Matrix ret;57 for(ret.set_size(base.row), memcpy(ret.d, base.d, sizeof base.d); index; index >>= 1, base = base * base)58 if(index & 1) ret = ret * base;59 return ret;60 }61 };62 using namespace my_matrix;63 64 int hash[1000 + 20], top;65 inline int id(int x) {66 if(hash[x] != -1) return hash[x];67 else return hash[x] = top++;68 }69 int T, S, E, N;70 long long g[103][103];71 72 int main() {73 freopen("relays.in", "r", stdin);74 freopen("relays.out", "w", stdout);75 memset(hash, -1, sizeof hash);76 scanf("%d%d%d%d", &N, &T, &S, &E);77 memset(g, INF, sizeof g);78 for(int i = 1; i <= T; ++i) {79 int l, f, t;80 scanf("%d%d%d", &l, &f, &t);81 g[id(f)][id(t)] = g[id(t)][id(f)] = l;82 }83 Matrix base;84 base.set_size(top);85 memcpy(base.d, g, sizeof g);86 base = fast_pow(base, N - 1);87 printf("%lld\n", base.d[id(S)][id(E)]);88 }
Relays