BZOJ_[usaco2007 Nov]relays Cow Relay Run_Discretization + Multiplication Freud
Description
FJ's N (2 <= N <= 1,000,000) cows chose relay running as their daily exercise program. As for the location of the relay run, it is naturally on the existing T (2 <= T <= 100) tracks in the pasture. The runways on the farm have some junctions, and each runway connects two different junctions I1_i and I2_i (1 <= I1_i <= 1,000; 1 <= I2_i <= 1,000). Each junction 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 junctions each runway connects to, and no two junctions are directly connected by two different runways. You can think of these junctions and runways as forming a picture. To complete a relay run, all N cows must stand at a junction (some junctions may have more than 1 cow) before the run begins. Of course, their positions must ensure that they can pass the baton in sequence, and the last cow holding the baton will stop at the preset end point. Your task is to write a program that calculates the minimum possible total length of the cow's running path given the start (S) and end (E) of the relay run. Obviously, this path must pass exactly N runways.
Input
* Line 1: 4 integers separated by spaces: N, T, S, and E
* Lines 2..T+1: i+1 is 3 integers separated by spaces: length_i, I1_i, and I2_i, describing the i-th runway.
Output
* Line 1: Output a positive integer, indicating the minimum length of the path that starts at S, ends at E, and passes exactly N runways
Sample Input
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9
Sample Output
/************************** orzzZZZZzZzZzzZzZZzZzZzzZ ***************************/ #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int len,n,m,d[250],xx[250],yy[250],turn[1500],s,t,zz[250]; void mnm(int &x,int y){ if(x>y) x=y; } struct Mat { int v[203][203]; Mat(){memset(v,0x3f,sizeof(v));} Mat operator*(const Mat &x) const { Mat re;int i,j,k; for (k = 1; k <= only; k ++) { for(i=1;i<=len;i++) { for(j=1;j<=len;j++) { re.v [i] [j] = min (re.v [i] [j], v [i] [k]+xv [k] [j]); } } } return re; } }; Mat qp(Mat x,int y) { Mat I; int i,j; for(i=1;i<=len;i++) { Iv [i] [i] = 0; } while(y) { if(y&1) I=I*x; x=x*x; y>>=1; } return I; } int main() { scanf("%d%d%d%d",&n,&m,&s,&t); int i; for(i=1;i<=m;i++) { scanf("%d%d%d",&zz[i],&xx[i],&yy[i]); d[i]=xx[i],d[i+m]=yy[i]; } sort(d+1,d+2*m+1); turn[s]=len=1; for(i=1;i<=2*m;i++) { if(d[i]==s||d[i]==t) continue; if(d[i]!=d[i-1]) len++; turn[d[i]]=len; } turn[t]=++len; Mat x; //for(i=1;i<=len;i++) x.v[i][i]=0; for(i=1;i<=m;i++) { mnm(x.v[turn[xx[i]]][turn[yy[i]]],zz[i]); x.v[turn[yy[i]]][turn[xx[i]]]=x.v[turn[xx[i]]][turn[yy[i]]]; } Mat T=qp(x,n); printf("%d\n",T.v[1][len]); }