【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
*/