本题的大意就是问从S 到 T 经过边得个数恰为k的最短路是多少。
如果学过离散数学 就应该知道 邻接矩阵A
A^1里的元素a[i][j] 代表i到j的走一步一条路;
A^2里的元素a[i][j] 代表i到j的走两步一条路 ;
A^n里的元素a[i][j] 代表i到j的走N步一条路 ;
然后再矩阵快速幂一下就好
代码如下
/*
* Author : Echo
* Email : 1666424499@qq.com
* Description :
* Created Time : 2017/10/6 18:08:21
* Last Modify : 2017/10/6 19:02:49
* File Name : a.cpp
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
#define LL long long
#define mem(a,k) memset(a,k,sizeof(a))
#include <map>
using namespace std;
const int maxint = -1u>>1;
const int maxn=2e2+100;
const int maxm=1e4+100;
int cnt=0;
struct node{
int an[maxn][maxn];
void set(){
for(int i=1;i<=200;i++)
for(int j=1;j<=200;j++)
an[i][j]=1e9;
}
void copy(node a){
for(int i=1;i<=cnt;i++)
for(int j=1;j<=cnt;j++)
an[i][j]=a.an[i][j];
}
node cal(node a,node b){
node res;
res.set();
for(int i=1;i<=cnt;i++)
for(int k=1;k<=cnt;k++)
for(int j=1;j<=cnt;j++)
if(res.an[i][j]>a.an[i][k]+b.an[k][j])
res.an[i][j]=a.an[i][k]+b.an[k][j];
return res;
}
}road,ans;
void QSM(int n){
ans.copy(road);
n--;
while(n){
if(n%2==1){
ans=ans.cal(ans,road);
}
road=road.cal(road,road);
n>>=1;
}
}
int main(){
int n,m,s,t;
cin>>n>>m>>s>>t;
map<int,int >mp;
road.set();
for(int i=1;i<=m;i++){
int a,b,c;
cin>>c>>a>>b;
if(mp[a]==0)mp[a]=++cnt;
if(mp[b]==0)mp[b]=++cnt;
//printf("%d:%d;%d:%d %d\n",a,mp[a],b,mp[b],road.an[mp[a]][mp[b]]);
if(road.an[mp[a]][mp[b]]>c){
road.an[mp[a]][mp[b]]=c;
road.an[mp[b]][mp[a]]=c;
}
}
QSM(n);
//printf("%d %d\n",mp[s],mp[t]);
printf("%d\n",ans.an[mp[s]][mp[t]]);
return 0;
}
/*
2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9
10
*/