用矩阵来表示两个点之间走k步的最短路,然后快速幂。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
using namespace std;
typedef long long ll;
const int maxn=1e3+9;
set <int> q;
int a[maxn];
int f[maxn][maxn];
long long d[211][211];
const long long inf=(ll)1111111111111;
ll tt[211][211];
void cal(ll a[211][211],ll b[211][211],ll c[211][211],int n)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
tt[i][j]=inf;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(b[i][k]+c[k][j]<tt[i][j])
tt[i][j]=b[i][k]+c[k][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=tt[i][j];
}
long long work(int m,int n,int from,int to)
{
long long ans[211][211];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans[i][j]=inf;
ans[from][from]=0;
while(m)
{
if(m&1)
cal(ans,ans,d,n);
cal(d,d,d,n);
m/=2;
}
return ans[from][to];
}
int main()
{
int n,t,s,e;
// scanf("%d %d %d %d",&n,&t,&s,&e);
while(scanf("%d %d %d %d",&n,&t,&s,&e)!=EOF)
{
memset(f,0,sizeof(f));
memset(d,11,sizeof(d));
q.clear();
for(int i=1,from,to,w;i<=t;i++)
{
scanf("%d %d %d",&w,&from,&to);
f[from][to]=f[to][from]=w;
q.insert(from);
q.insert(to);
}
int k=0;
for(set<int>:: iterator i=q.begin();i!=q.end();i++)
a[*i]=++k;
for(int i=1;i<=1000;i++)
for(int j=1;j<=1000;j++)
if(f[i][j])
d[a[i]][a[j]]=f[i][j];
cout<<work(n,k,a[s],a[e])<<endl;
}
return 0;
}