欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【SSL 1493】货员的难题【图论】

程序员文章站 2024-03-19 08:33:28
...

Description

某乡有 n 个村庄( 1 < n <40 ),有一个售货员,他要到各个村庄去售货,各村庄之间的路程 s(0<s<1000) 是已知的,且 A 村与 B 村与 B 村与 A 村的路大多不同,为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为 1 ,他不知道选择什么样的路才能使所走的路程最短,请你帮助他选择一条路径。

Input

村庄数 n 和各村之间的路程(均是整数)

Output

最短路程

Sample Input

3 // 村庄数量 
0 2 1 // 村庄 1 到各村的路程 
1 0 2 	
2 1 0 

Sample Output

3

说明&分析:
邮递员从某一个村子A出发;每个村子访问仅且访问一次,最后到达村子B结束,从A到B的路线成为哈密顿路。
如果A和B重合,即回到出发点,称为哈密顿回路。所以就可以用 哈密顿回路+深搜邻接表 做。

直接上代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,g[1001][1001],ans=99999,l;
bool vis[1001];
struct node{
	int x,next;
}a[1001][1001];
int c[1001],minn=99999;
void dfs(int p,int cnt,int sum)
{  //深搜函数
	if(cnt==n)
	{
		ans=min(ans,sum+c[p]);
		return;
	}
	if(sum+(n-cnt)+1>ans) return;
	if(sum>ans) return;
	for(int i=2;i<=n;i++)
	{
		if(!vis[a[p][i].next])
		{
			int v=sum+a[p][i].x;
			if(v>ans) return;
			if(v+n-cnt+minn>ans) return;
			vis[a[p][i].next]=1;
			dfs(a[p][i].next,cnt+1,sum+a[p][i].x);
			vis[a[p][i].next]=0;
		}
	}
}
bool cmp(node x,node y)
{
	return x.x<y.x;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>l;
			a[i][j].x=l;  //读入邻接表
			a[i][j].next=j;
			g[i][j]=l;
		}
		c[i]=a[i][1].x;
		if(i!=1)
		{
			minn=min(minn,c[i]);
		}
		sort(a[i]+1,a[i]+1+n,cmp);
	}
	vis[1]=1;
	dfs(1,1,0);
	cout<<ans;
	
	return 0;
}
/*
3
0 2 1 
1 0 2 	
2 1 0 
*/