Title Description
Input Format
Output Format
Sample
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 */