HDU 1072 记忆化搜

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;
}

猜你喜欢

转载自blog.csdn.net/henu_1710252529/article/details/81701954