题意:tsp问题,但是每个点可以最多走两次
链接:点我
转移方程见代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define inf 0x3f3f3f3f int State[12]; int vis[60000][12]; int dp[60000][12]; int map[12][12]; int n,m; void Initiate() { State[0]=1; for(int i=1;i<=10;i++) State[i]=State[i-1]*3; //初始城市 for(int i=0;i<=State[10];i++) { int tmp=i; for(int j=0;j<=10;j++) //点j在状态里出现的次数 { vis[i][j]=tmp%3; tmp/=3; } } } int main() { Initiate(); int u,v,w,ans; #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); #endif while(~scanf("%d%d",&n,&m)){ memset(dp,inf,sizeof(dp)); memset(map,inf,sizeof(map)); for(int i=0;i<n;i++)dp[State[i]][i]=0; while(m--){ scanf("%d%d%d",&u,&v,&w); u--,v--; map[u][v]=map[v][u]=min(map[u][v],w); } ans=inf; for(int i=0;i<State[n];i++) //枚举起点 { bool flag=true; for(int j=0;j<n;j++) //枚举终点 { if(vis[i][j]==0) flag=false;//是否每个城市都至少走了1次 if(dp[i][j]==inf) continue; for(int k=0;k<n;k++) //枚举另一点 if(j!=k) { if(vis[i][k]>=2)continue; if(map[j][k]==inf)continue; dp[i+State[k]][k]=min(dp[i+State[k]][k],dp[i][j]+map[j][k]); } } if(flag) { for(int j=0;j<n;j++) { ans=min(ans,dp[i][j]); } } } if(ans==inf) ans=-1; printf("%d\n",ans); } return 0; }
时间: 2024-09-30 18:52:46