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

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
#include
#include
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 
*/

你可能感兴趣的:(图论,SSLOnlineJudge)