转自:http://www.cnblogs.com/20143605--pcx/p/4926174.html
这个地方我原本打算用 node结构体中 存上remain的,,但是这样的话自己觉得代码太长而且分类讨论太多。(其实我的一些分类讨论有点多余。。或者说其实可以更加精短的。。)
然后看了别人用的这个Floyd的,,挺好的。。
而且大概知道了为什么会有vis的二维数组,,因为这样判重中才有k的次数。。。才能体现spfa的快速
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<stack>
#include<cmath>
#include<map>
#include<vector>
#define ll long long
#define inf 0x3f3f3f3f
#define INF 1e9
#define bug1 cout<<"bug1"<<endl;
#define bug2 cout<<"bug2"<<endl;
#define bug3 cout<<"bug3"<<endl;
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
int a,b;
const int maxn=105;
int l,k,m;
int d[maxn][12];
int vis[maxn][12];
int head[maxn];
int e[maxn][maxn];
struct Node{
int u;
int k;
Node(int _u,int _k):u(_u),k(_k){}
};
int spfa(){
mem(d,inf);
mem(vis,0);
queue<Node>q;
int n=a+b;
vis[n][k]=1;
q.push(Node(n,k));
for(int i=0;i<=k;++i){
d[n][i]=0;
}
while(!q.empty()){
Node top=q.front();q.pop();
int u=top.u;
int k=top.k;
vis[u][k]=0;
for(int v=1;v<=n;++v){
if(v==u||e[u][v]==inf)continue;
if(d[v][k]>d[u][k]+e[u][v]){
d[v][k]=d[u][k]+e[u][v];
if(!vis[v][k]){
vis[v][k]=1;q.push(Node(v,top.k));
}
}
if(k>0&&l>=e[u][v]&&d[v][k-1]>d[u][k]){
d[v][k-1]=d[u][k];
if(!vis[v][k-1]){
vis[v][k-1]=1;
q.push(Node(v,top.k-1));
}
}
}
}
int ans=inf;
for(int i=0;i<=k;++i){
ans=min(ans,d[1][i]);
}
pf("%d\n",ans);
}
void floyd(){
int n=a+b;
for(int k=1;k<=a;++k){//这个地方是a。
for(int i=1;i<=n;++i){下面这里不是a,是n
for(int j=1;j<=n;++j){
if(e[i][k]!=inf&&e[k][j]!=inf&&e[i][j]>e[i][k]+e[k][j]){
e[i][j]=e[i][k]+e[k][j];
}
}
}
}
}
int main(){
int T;
sf("%d",&T);
while(T--){
sf("%d%d%d%d%d",&a,&b,&m,&l,&k);
mem(e,inf);
for(int i=1;i<=m;++i){
int u,v,c;
sf("%d%d%d",&u,&v,&c);
e[u][v]=e[v][u]=min(e[v][u],c);
}
floyd();
spfa();
}
}