BZOJ_[usaco2007 Nov]relays Cow Relay Run_Discretization + Multiplication Freud

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

2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9

Sample Output

10

The number of points is 1000, but the number of sides is only 100. It can be found that there are only 200 useful points, so discretize it.
Then F[i][j][k] represents the shortest path from i to j through k edges.
Moment multiplication can be optimized.
 
Code:
/**************************
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]);
}

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325354787&siteId=291194637