dp版
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const int N=100;
const int M=2000+10;
const int INF=1e8;
int dp[N][1<<10],s[N];
int dis[N][N];
int n,m,k;
void floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
}
void _stn(int ed){
floyd();
for(int y=0;y<ed;y++){
for(int x=1;x<=n;x++)dp[x][y]=INF;
}
for(int i=1;i<=n;i++){
if(i<=k)s[i]=1<<(i-1),dp[i][s[i]]=0;
else if(i>=n-k+1)s[i]=1<<(n-i+k),dp[i][s[i]]=0;
else s[i]=0;
}
for(int y=0;y<ed;y++){
for(int x=1;x<=n;x++){
for(int i=(y-1)&y;i;i=(i-1)&y){
dp[x][y]=min(dp[x][y],dp[x][i|s[x]]+dp[x][(y-i)|s[x]]);
}
}
for(int x=1;x<=n;x++){
for(int x1=1;x1<=n;x1++){
dp[x1][y|s[x1]]=min(dp[x1][y|s[x1]],dp[x][y]+dis[x][x1]);
}
}
}
}
spfa版
//hdu 4085
int vis[N][1<<10];
int dp[N][1<<10],s[N];
queue<int> qq;
int update(int x,int y,int w){
if(dp[x][y]>w){
dp[x][y]=w;return 1;
}
return 0;
}
void spfa(){
while(!qq.empty()){
int x=qq.front()/10000,y=qq.front()%10000;
vis[x][y]=0;
qq.pop();
for(int i=head[x];i!=-1;i=e[i].next){
int v=e[i].v,w=e[i].w;
if(update(v,y|s[v],dp[x][y]+w)&&y==(y|s[v])&&!vis[v][y]){
vis[v][y]=1,qq.push(v*10000+y);
}
}
}
}
int n,m,k;
void _stn(int ed){
for(int y=0;y<ed;y++){
for(int x=1;x<=n;x++)dp[x][y]=INF;
}
for(int i=1;i<=n;i++){
if(i<=k)s[i]=1<<(i-1),dp[i][s[i]]=0;
else if(i>=n-k+1)s[i]=1<<(n-i+k),dp[i][s[i]]=0;
else s[i]=0;
}
memset(vis,0,sizeof(vis));
for(int y=0;y<ed;y++){
for(int x=1;x<=n;x++){
for(int i=(y-1)&y;i;i=(i-1)&y){
dp[x][y]=min(dp[x][y],dp[x][i|s[x]]+dp[x][(y-i)|s[x]]);
}
if(dp[x][y]<INF){
qq.push(x*10000+y);vis[x][y]=1;
}
}
spfa();
}
}