/*
不会什么树形DP,我做的是spfa(其实floyed就可以)+深搜+剪枝
首先将边反向,spfa处理所有点到1的距离,以备剪枝使用
然后深搜得到答案
剪枝:利用spfa得到的距离,当当前的dis+(n-t)*minn+f[x]>ans时,剪枝
(minn是矩阵中的最短距离,n-t是还有几步可以遍历完所有的村庄)
*/
#include<cstring>
#include<cstdio>
#include<iostream>
#include<queue>
#define M 20
#define INF 3000000
using namespace std;
int map[M][M],f[M],n,ans=INF,min1=INF;
int a2[M][M];
bool vis[M];
queue<int> q;
int read()
{
char c=getchar();int num=0,flag=1;
while(c<‘0‘||c>‘9‘){if(c==‘-‘)flag=-1;c=getchar();}
while(c>=‘0‘&&c<=‘9‘){num=num*10+c-‘0‘;c=getchar();}
return num*flag;
}
void dfs(int x,int t,int dis)
{
if(dis>ans)return;
if(dis+(n-t)*min1+f[x]>ans)return;
if(t==n)
{
ans=min(ans,dis+map[x][1]);
return;
}
for(int i=1;i<=n;i++)
if(!vis[i])
{
vis[i]=true;
dfs(i,t+1,dis+map[x][i]);
vis[i]=false;
}
}
void spfa()
{
q.push(1);
vis[1]=1;
f[1]=0;
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=1;i<=n;i++)
if(a2[x][i]&&f[x]+a2[x][i]<f[i])
{
f[i]=f[x]+a2[x][i];
if(!vis[i])
{
vis[i]=1;
q.push(i);
}
}
}
}
int main()
{
memset(f,0x3f3f3f3f,sizeof(f));
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
map[i][j]=read();
a2[j][i]=map[i][j];
min1=min(min1,map[i][j]);
}
spfa();
memset(vis,0,sizeof(vis));
vis[1]=1;
dfs(1,1,0);
printf("%d",ans);
return 0;
}
#include<cstdio>
#include<cstring>
using namespace std;
#define N 51
int n,tr[N][N],m=0x7fffffff;
bool vis[N];
void run(int p,int d,int s){
int r;
if(d==n){
if(s+tr[p][1]<m) m=s+tr[p][1];
return;
}
for(r=1;r<=n;r++){
if(!vis[r]&&tr[p][r]>0){
if(s+tr[p][r]>=m) break;
vis[r]=1;
run(r,d+1,s+tr[p][r]);
vis[r]=0;
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&tr[i][j]);
vis[1]=1;
run(1,1,0);
printf("%d",m);
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[20],map[16*16][16*16];
int n,a,b,c,sum=0x7f7f7f7f;
void Dfs(int s ,int dis,int k)
{
f[s]=1;
if((dis+(n-k))>=sum) return;
if(k==n)
{
sum=min(sum,dis+map[s][1]);
}
for(int i=1;i<=n;i++)
{
if(f[i]==0)
{
Dfs(i,dis+map[s][i],k+1);
f[i]=0;
}
}
}
int main()
{
cin>>n;
memset(f,0,sizeof f );
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&map[i][j]);
Dfs(1,0,1);
printf("%d",sum);
return 0;
}