(填坑)數學建模之旅行路線規劃問題(狀壓+Dijkstra)
阿新 • • 發佈:2018-12-20
最近突然想起很久以前同學問的一道數模題,是道NP問題,當時不會搞,現在發現用狀壓可以搞出來,所以就把這個坑填上了
雖然題目說每個景點可以經過多次,但最優路線還是每個景點都只經過了一次,囧...
#define FRER() freopen("i.txt","r",stdin); #define FREW() freopen("o.txt","w",stdout); #include<bits/stdc++.h> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int N=10; int dis[N][N]= { {0,300,360,210,590,475,500,690}, {300,0,380,270,230,285,200,390}, {360,380,0,510,230,765,580,770}, {210,270,510,0,470,265,450,640}, {590,230,230,470,0,515,260,450}, {475,285,765,265,515,0,460,650}, {500,200,580,450,260,460,0,190}, {690,390,760,640,450,650,190,0}, }; int d[1<<N][N],vis[1<<N][N]; struct node { int S,u; node(int S=0,int u=0):S(S),u(u) {} bool operator<(const node& b)const { return d[S][u]>d[b.S][b.u]; } }; node pre[1<<N][N]; void printans(int S,int u) { if(u!=0)printans(pre[S][u].S,pre[S][u].u); printf("%d ",u); } int Dij() { memset(d,INF,sizeof d); memset(vis,0,sizeof vis); priority_queue<node> q; q.push(node(1<<0,0)); d[1<<0][0]=0; vis[1<<0][0]=1; while(!q.empty()) { int S=q.top().S,u=q.top().u; q.pop(); if(u==7)continue; for(int v=1; v<8; ++v) { int S2=S|(1<<v); if(d[S2][v]<=d[S][u]+dis[u][v])continue; d[S2][v]=d[S][u]+dis[u][v]; pre[S2][v]=node(S,u); if(!vis[S2][v]) { vis[S2][v]=1; q.push(node(S2,v)); } } } return d[(1<<8)-1][7]; } int main() { //FRER(); printf("%d\n",Dij()); printans((1<<8)-1,7); return 0; }