https://cn.vjudge.net/problem/15705/origin
dfs的一道好题,注意减枝
题意:要求从第一个星球遍历访问其他星球,然后输出遍历每个星球所用时间的总和,就酱
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=33;
int a[maxn][maxn];
int b[maxn][maxn];
int falg[maxn];
int as1;
int flag[maxn];
#define mxn 1099999999
void flody(int n)用此算法更新最短路
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(j!=i)
{
for(int k=1;k<=n;k++)
{
if(k!=j&&k!=i)
{
a[j][k]=min(a[j][k],a[j][i]+a[i][k]);
}
}
}
}
}
}
void dfs(int n,int i1,int ans,int l2,int c)///n代表总数,i1代表已经加入路程的数,ans代表总和,l2代表着上一个的位置///c代表当前所用时间的总和
{
if(c>=as1)
return ;
if(i1==n)
{
as1=min(as1,c);
return ;
}
for(int i=2;i<=n;i++)///如果当前时间加上到达还未到达的某个星球的时间大于规定时间,那么,就删除、舍弃该路径,return
因为之前已经Floyd过了,不会再有比这更短的路了,所以不会误删
{
if(flag[i]&&ans+a[l2][i]>falg[i])
return ;
}
for(int i=2;i<=n;i++)
{
if(flag[i] )
{
flag[i]=0;
dfs(n,i1+1,ans+a[l2][i],i,c+a[l2][i]*(n-i1));
flag[i]=1;
}
}
}
int main()
{
int n;
ios::sync_with_stdio(false);
while (cin>>n) {
as1=1099999999;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
}
memset(flag,-1,sizeof(flag));
for(int i=2;i<=n;i++)
cin>>falg[i];
flody(n);
dfs(n,1,0,1,0);
if(as1==mxn)
cout<<"-1"<<endl;
else
cout<<as1<<endl;
}
return 0;
}