dp[state][i] 状态为state时最后到达点i
先用floyd算出最短路,然后用dp[state][i]=min(dp[state][j],dp[state2][j]+mp[j][i]
QAQ血的教训就是要写成(1<<(i+1))-1,不能是1<<(i+1)-1 (我改了一上午)
优先级【高到低】:
第一级:圆括号【()】、下标运算符【[]】、分量运算符的指向结构体成员运算符【->】、结构体成员运算符【.】
第二级:逻辑非运算符【!】、按位取反运算符【~】、自增自减运算符【++ –】、负号运算符【-】、类型转换运算符【(类型)】、指针运算符和取地址运算符【*和&】、长度运算符【sizeof】
第三级:乘法运算符【*】、除法运算符【/】、取余运算符【%】
第四级:加法运算符【+】、减法运算符【-】
第五级:左移动运算符【<<】、右移动运算符【>>】
第六级:关系运算符【< > <= >= 】
第七级:等于运算符【==】、不等于运算符【!=】
第八级:按位与运算符【&】
第九级:按位异或运算符【^】
第十级:按位或运算符【|】
第十一级:逻辑与运算符【&&】
第十二级:逻辑或运算符【||】
第十三级:条件运算符【?:】
第十四级:赋值运算符【= += -= *= /= %= >>= <<.= &= |= ^=】
第十五级:逗号运算符【,】
代码
/* id:gww language: */ #include<bits/stdc++.h> using namespace std; const int N=10+2; const int inf=0x3f3f3f3f; int n,mp[N][N];//各地状态 int dp[1<<N][N];//状态为i时目的地为j的最短时间 inline int read() //This is 读入优化 { int x=0,w=0;char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return w?-x:x; } void floyd() { for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) for(int k=0;k<=n;++k)//计算到各点的最短路 mp[i][j]=min(mp[i][k]+mp[k][j],mp[i][j]); } int main() { memset(dp,inf,sizeof(dp)); n=read(); int v=(1<<(n+1))-1; for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) mp[i][j]=read();//i地到j地的时间 floyd(); for(int sta=0;sta<=v;++sta)//所有状态 { for(int i=0;i<=n;++i)//到所有点 { if(sta&(1<<i))//如果经过i点 { if(sta==(1<<i)) dp[sta][i]=mp[0][i];//如果只经过i else { for(int k=0;k<=n;++k)//中间点 if((sta&(1<<k))&&k!=i)//经过k点 dp[sta][i]=min(dp[sta][i],dp[sta^(1<<i)][k]+mp[k][i]); //在没经过i点的状态中 } } } } int ans=inf; for(int i=0;i<=n;++i) /*{ printf("%d ",dp[v][i]+mp[i][0]); }*/ ans=min(ans,dp[v][i]+mp[i][0]); printf("%d",ans); return 0; }