Topic: Given a graph, requires starting from the first point, according to a topological sequence of all the nodes of the 2~k+1, and then reach N, the shortest path
First, the shortest circuit between all the key points is SPFA and the pressure DP
F[STATE][P] Indicates that the point set that has been traversed is state and will go to the shortest point of P
Just a memory search--
Standard cards are over--
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 20200using namespace std;struct abcd{int to,f,next;} Table[200200<<1];int head[m],tot;int n,m,k;int map[30][30],topology_map[23];int f[1<<21][23];void Add ( int X,int Y,int z) {table[++tot].to=y; Table[tot].f=z; TABLE[TOT].NEXT=HEAD[X]; Head[x]=tot;} void SPFA (int s) {static int q[65540],f[m]; static unsigned short r,h; static bool V[m]; int i; Memset (f,0x3f,sizeof f); q[++r]=s;f[s]=0; while (r!=h) {int x=q[++h];v[x]=0; for (I=head[x];i;i=table[i].next) if (F[TABLE[I].TO]>F[X]+TABLE[I].F) {f[table[i].t O]=F[X]+TABLE[I].F; if (!v[table[i].to]) v[table[i].to]=1,q[++r]=table[i].to; }} for (i=1;i<=k+1;i++) map[i][s<=k+1?s:k+2]=f[i];} int STATE_COMPRESSED_DP (int state,int p) {if (F[state][p]) return f[state][p]; IF (!state) return 0; int i; f[state][p]=0x3f3f3f3f; for (i=1;i<=k+1;i++) if (state& (1<<i-1) && (topology_map[i]&state) ==0) f[state] [P]=min (F[STATE][P],STATE_COMPRESSED_DP (state^ (1<<i-1), i) +map[i][p]); return f[state][p];} int main () {//freopen ("atr11b.in", "R", stdin); int i,x,y,z,temp; cin>>n>>m>>k; for (i=1;i<=m;i++) {scanf ("%d%d%d", &x,&y,&z); ADD (x, y, z); ADD (Y,X,Z); } cin>>temp; for (i=1;i<=temp;i++) {scanf ("%d%d", &x,&y); topology_map[x]|=1<<y-1; } for (i=2;i<=k+1;i++) topology_map[1]|=1<<i-1; for (i=1;i<=k+1;i++) SPFA (i); SPFA (n); COUT<<STATE_COMPRESSED_DP ((1<<k+1) -1,k+2) <<endl; return 0;}
Bzoj 1097 POI2007 Tourist Attractions ATR spfa+ pressure DP