void-man

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

有1-N个城市,并且给出城市之间的长度,还有花费,注意,相同城市之间可能有好几条道路,问最后花费不超过K,从城市1到N的最短距离

直接暴力dfs,然后再稍微剪枝一下就可以过,关键是处理两个城市间的多条路,在这里用邻接表处理,在搜索时候如果已经找到一组长度,在循环时候

若当前长度小于已经找到长度,就不用再dfs了,还有就是注意标记数组

#include <stdio.h>
#include <string.h>
#define MIN(a,b) (a)<(b)?(a):(b)
#define N 105
#define inf 1e8
struct city
{
	int ed,len,to;
	city *next;
};
city g[N];
city c[N*N];
int result,ci,mo,ca;
bool used[N];
void init()
{
	for(int i=0;i<=ca;i++)
		c[i].next=NULL;
    for(int i=1;i<=ci;i++)
    g[i].next=NULL;
	memset(used,false,sizeof(used));
	result=inf;
}
void dfs(int n,int left,int len)
{
	if(n==ci&&left>=0)
	{
		result=MIN(result,len);
		return ;
	}
	if(left<0)return ;
	for(city *i=g[n].next;i!=NULL;i=i->next)
	{
	    //printf("left: %d from %d to %d  len %d mo %d\n",left,n,i->ed,i->len,i->to);
		if(!used[i->ed]&&len+i->len<result&&left-i->to>=0)
		{
			used[i->ed]=true;
			//result=len+i->len
			dfs(i->ed,left-i->to,len+i->len);
			used[i->ed]=false;
		}

	}
}
int main()
{
	int so,de,le,to,cnt;
	city *tmp;
	//freopen("1724.in","r",stdin);
	while(scanf("%d%d",&mo,&ci)!=EOF)
	{
		cnt=0;
		init();
		scanf("%d",&ca);
		for(int i=0;i<ca;i++)
			{
			scanf("%d%d%d%d",&so,&de,&le,&to);
			tmp=&c[cnt++];
			tmp->ed=de;tmp->len=le;tmp->to=to;
			tmp->next=g[so].next;
			g[so].next=tmp;
			//printf("%d %d  %d\n",tmp->ed,tmp->len,tmp->to);
			}
        dfs(1,mo,0);
        if(result==inf)printf("-1\n");
        else printf("%d\n",result);


	}
	return 0;
}
posted on 2011-06-03 22:45  void-man  阅读(343)  评论(0)    收藏  举报