[Usaco2007 Nov] relays Relay stray cows Solutions overload matrix multiplication

Title Description

FJ of N (2 <= N <= 1,000,000) cows selected as the relay to run their daily exercise program. As the relay locations to run the existing natural T (2 <= T <= 100) on the runway in a pasture. On some farms the runway intersection, each runway are connected to two different intersection I1_i and I2_i (1 <= I1_i <= 1,000; 1 <= I2_i <= 1,000). Each intersection is the endpoint of at least two runways. Cows know each runway length length_i (1 <= length_i <= 1,000), and connecting the intersection of each runway number and no two junctions are connected directly by the two different runways. You can think of these constitute a meeting point and a view of the runway. In order to complete a relay race, all N cows before running start all stand on one intersection (probably standing on some meeting point not only a cow). Of course, their stations to ensure that they can in turn pass the baton, and finally holding stick cow to stop at a preset destination. Your task is to write a program that calculates in the case of relay race starting point (S) and end (E) determined cows running the smallest possible total path length. Obviously, this path must go through exactly N runways.

Input Format

Line 1: 4 with a space-separated integers: N, T, S, and E
+ 1 line 2..T: i + 1 of three integers separated by a space: length_i, I1_i, and I2_i He describes the i-th runway.

Output Format

Line 1: Output a positive integer indicating the starting point is S, the end of E, N and right across the path of the minimum length of the runway

Sample

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

  Ideas: First, the idea to question and SCOI2009 lost a similar problem, I do not tend to this problem is called the multiplier floyd, I think this question better understood from the perspective of the matrix, and can prove the correctness, apparently from getting lost we get so few ideas condition, a number of paths is a matrix memory, is a few steps away. So the analogy a bit, we were required k times the number of paths, then we ask shortest k edges, then it is easy to think of us, which kept the edge weight matrix, representing the shortest path to j i take a side, then we yy what may, this matrix k i is the power to take the shortest path j k edges, then obviously before the matrix multiplication can not be calculated, so we thought about the overload matrix multiplication, becomes c [i ] [j] = min (a [i] [k] + a [k] [j]), which is multiplied many online floyd origin, but the next step is to ask, floyd can double it? Another problem is that this is done right? So we need this line of thinking, we prove that we have not been overloaded commutative matrix operations, namely (a @ a) @ a == a @ (a @ a); then it should be the right of the algorithm sex, we consider the actual meaning, walk 2 steps to walk one step, and go one step walk two steps, the shortest necessarily the same. Of course, I did not say doubling floyd wrong, break out the code are the same, which are all personal opinions.

 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=105,ID=1000,inf=0x7fffffff;
int p[ID],m[N][N],l[N],n,k,s,e,cnt;
struct mat
{
    long long a[105][105],n;
    mat (int n,int x) :n(n)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            a[i][j]=x;
    }
    mat operator *(mat &b)
    {
        mat c(n,inf);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++)
                c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
        return c;
    }
    void print()
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            if(a[i][j]==inf) printf("# ");
            else cout<<a[i][j]<<" ";
            cout<<endl;
        }
    }
};
int rd()
{
    char cc=getchar();
    int s=0,w=1;
    while(cc<'0'||cc>'9') {if(cc=='-') w=-1;cc=getchar();}
    while(cc>='0'&&cc<='9') s=(s<<3)+(s<<1)+cc-'0',cc=getchar();
    return s*w;
}
mat qpow(mat a,int k)
{
    mat ans=a;
    for(;k;k>>=1,a=a*a)if(k&1) ans=ans*a;
    return ans;
}
int main()
{
    k=rd(),n=rd(),s=rd(),e=rd();
    for(int i=1,z,x,y;i<=n;i++)
    {
        z=rd(),x=rd(),y=rd();
        if(!p[x]) p[x]=++cnt;
        if(!p[y]) p[y]=++cnt;
        //printf("%d %d\n",p[x],p[y]);
        m[p[x]][p[y]]=z;
        m[p[y]][p[x]]=z;
    }
    mat a(cnt,0);
    for(int i=1;i<=cnt;i++)
        for(int j=1;j<=cnt;j++)
            a.a[i][j]=m[i][j]?m[i][j]:inf;
    //a.print();
    mat c=qpow(a,k-1);
    //c.print();
    printf("%lld\n",c.a[p[s]][p[e]]);
}
/*
g++ 1.cpp -o 1
./1
2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9
*/
View Code

 

Guess you like

Origin www.cnblogs.com/starsing/p/11204753.html