洛谷P1171 售货员的难题
题目背景
数据有更改
题目描述
某乡有n个村庄(1<n<20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且A村到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。
输入输出格式
输入格式:
村庄数n和各村之间的路程(均是整数)。
输出格式:
最短的路程。
输入输出样例
说明
输入解释
3 {村庄数}
0 2 1 {村庄1到各村的路程}
1 0 2 {村庄2到各村的路程}
2 1 0 {村庄3到各村的路程}
/* 洛谷上只能到90分qwq */ #include<iostream> #include<cstdio> #define maxn 20 int n,num,head[maxn],ans=0x7fffffff; struct node{ int to,pre,v; }e[maxn*maxn]; bool vis[maxn]; using namespace std; void Insert(int from,int to,int v){ e[++num].to=to; e[num].v=v; e[num].pre=head[from]; head[from]=num; } void dfs(int pos,int cnt,int dis){ if(dis>=ans)return; if(dis+n-cnt+1>=ans)return; for(int i=head[pos];i;i=e[i].pre){ int to=e[i].to; if(to==1&&cnt==n){ ans=min(ans,dis+e[i].v); return; } if(vis[to])continue; vis[to]=1; dfs(to,cnt+1,dis+e[i].v); vis[to]=0; } } int qread(){ int i=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();} return i; } int main(){ freopen("Cola.txt","r",stdin); n=qread(); int x; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ x=qread(); if(i!=j)Insert(i,j,x); } vis[1]=1; dfs(1,1,0); printf("%d",ans); }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,map[21][21],all,dp[21][1<<20],ans=0x7fffffff; int qread(){ int i=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();} return i; } int main(){ freopen("Cola.txt","r",stdin); //scanf("%d",&n); n=qread(); all=(1<<n)-1; for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)map[i][j]=qread(); memset(dp,0x3f,sizeof(dp)); dp[0][0]=0; for(int i=1;i<=n;i++)dp[i][1<<(i-1)]=map[1][i]; for(int s=0;s<=all;s++){ for(int i=1;i<=n;i++) if(s&(1<<(i-1))) for(int j=1;j<=n;j++) dp[i][s]=min(dp[i][s],dp[j][s^(1<<(i-1))]+map[j][i]); } for(int i=1;i<=n;i++)ans=min(ans,dp[i][all]+map[i][1]); printf("%d",ans); }
#include<iostream> #include<cstdio> #include<cstring> #define min(a,b) (a)>(b)?(b):(a) int n,map[21][21],all,dp[21][1<<20],ans=0x7fffffff,bit[21]; int qread(){ int i=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();} return i; } int main(){ freopen("Cola.txt","r",stdin); //scanf("%d",&n); bit[1]=1; for(int i=2;i<=20;i++)bit[i]=bit[i-1]<<1; n=qread(); all=(1<<n)-1; for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)map[i][j]=qread(); memset(dp,0x3f,sizeof(dp)); dp[1][1]=0; for(int s=1;s<=all;s+=2){ for(int i=1;i<=n;i++) if(dp[i][s]<=30000) for(int j=1;j<=n;j++) if(!(s&bit[j])) dp[j][s|bit[j]]=min(dp[j][s|bit[j]],dp[i][s]+map[i][j]); } for(int i=1;i<=n;i++)ans=min(ans,dp[i][all]+map[i][1]); printf("%d",ans); }