I used a keyword to search for my teammates and asked if I could be well trained ,,
HDU 3001 classic pressure DP
Probably .. M roads in N cities form a directed graph. N <= 10; then the person wants to travel. A Superman started to throw him to any city .. Then he wandered between cities. He wants to visit all the cities .. And. Each city can be visited twice at most. The shortest path is required .. If he cannot swim all the cities, then .. Output-1. Otherwise, the output is the shortest distance.
If you use search... Unreliable and search ,,
How to compress ?? Use an integer I to indicate his current status .. Obviously, two digits are required for a city .. 00 indicates that the account has not been to 01, indicating that the account has been to 10 at a time, indicating that the account has been to two times and then to a maximum of 10 cities ,.. So a total of 20 digits 2 ^ 20 are used .. 1024*1024 is about 10 ^ 6 .. Then DP [I] [J] indicates the current status .. And the Shortest Path in J City .. Then he can go to another city to check whether the time complexity is .. 10 ^ 6*10*10 plus various judgments .. Open an array of 10 ^ 6*10 and then MLE ,, we found that I is not continuous in the natural number, but discrete. We first find out that I meets the condition exists in an array Inn and then use binary search... It is equivalent to using a hash table and storing so many cases, and then DP is transferred ,,,,
MLE 1 wa1: Output-1 is not considered
The code is not long.
#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <cstdlib>#include <string>#include <queue>#include <cstring>#define CL(a,b) memset(a,b,sizeof(a))#define ll __int64#define TEST cout<<"TEST ***"<<endl;#define INF 0x7ffffff0#define MOD 100000000using namespace std;int inn[1000010];int dp[101000][11];int gra[15][15];int n,m,cii;int bin(int s,int e,int v){ int mid=(s+e)/2; if(inn[mid]==v)return mid; if(inn[mid]>v)return bin(s,mid,v); else return bin(mid+1,e,v);}int initinn(){ int i,ctt=0,taginn,teminn; for(i=0;i<=1100000;i++) { teminn=i;taginn=1; while(teminn) { if((teminn&3)==3) { taginn=0; break; } teminn=teminn>>2; } if(taginn==1) { inn[ctt++]=i; } } return ctt;}int main(){ cii=initinn(); while(scanf("%d %d",&n,&m)!=EOF) { CL(gra,-1); int i,j,k,a,b,w; int rem=INF; int ma=(1<<(2*n))-1; for(i=0;i<m;i++) { scanf("%d %d %d",&a,&b,&w); if(gra[a][b]==-1||gra[a][b]>w) { gra[a][b]=gra[b][a]=w; } } CL(dp,-1); for(i=0;i<=n;i++)dp[0][i]=0; for(i=0;i<=n;i++)gra[0][i]=gra[i][0]=gra[i][i]=0; for(i=0;inn[i]<=ma;i++) { a=inn[i]; for(j=1;j<=n;j++) { if(dp[i][j]==-1)continue; for(k=1;k<=n;k++) { if(gra[j][k]==-1)continue; b=k-1; if(a&(1<<(2*b+1)))continue; w=a+(1<<(2*b)); w=bin(1,cii,w); if(dp[w][k]==-1||dp[w][k]>dp[i][j]+gra[j][k]) dp[w][k]=dp[i][j]+gra[j][k]; } b=1; w=a; for(k=1;k<=n;k++) { if((w&3)==0) { b=0; break; } w=w>>2; } if(b==1&&dp[i][j]<rem)rem=dp[i][j]; } } if(rem==INF)rem=-1; printf("%d\n",rem); } return 0;}
HDU 3001 pressure DP