最近事情很多,没怎么做题,也没怎么想题,今天做华科月赛,果断悲剧了3题……
无语不在,这题果断用状态dp瞎搞,不知道有没有图论做法……坐等……
wa了八次,表示很无语,好像有重边,floyed写悲剧了,然后又忘了记录双向边,然后设正无穷结果忘了判断溢出了……各种wa……
dp[i][j]表示状态i时人停在j位置的最小不满意值。
上代码
#include <stdio.h> #define INF 1000000000 int map[20][20]; int dp[1<<16][16]; int n,m; int Min(int x,int y) { return x>y?y:x; } void Floyed() { int i,j,k; for (k=0;k<n;k++) { for (i=0;i<n;i++) { for (j=0;j<n;j++) { if (i!=j && j!=k && i!=k && map[i][k]!=INF && map[k][j]!=INF) { map[i][j]=Min(map[i][j],map[i][k]+map[k][j]); map[j][i]=Min(map[i][j],map[j][i]); } } } } } int Count(int t) { int s=0; while(t!=0) { if (t&1) s++; t>>=1; } return s; } void Test() { int i,j; for (i=0;i<(1<<n);i++) { for (j=0;j<n;j++) { printf("%10d ",dp[i][j]); } printf("/n"); } } int main() { int T,i,j,x,y,z,tag,k,ans; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); n++; for (i=0;i<n;i++) { for (j=0;j<n;j++) { if (i==j) map[i][j]=0; else map[i][j]=INF; } } for (i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); map[x][y]=Min(z,map[x][y]); map[y][x]=Min(z,map[y][x]); } Floyed(); for (i=0;i<(1<<n);i++) { for (j=0;j<n;j++) { dp[i][j]=INF; } } for (i=0;i<(1<<n);i++) { for (j=0;j<n;j++) { if ((i & (1<<j))==0) continue; if (i==1) { dp[i][j]=0; continue; } tag=i & ~(1<<j); for (k=0;k<n;k++) { if (((1<<k) & tag)==0) continue; if (map[k][j]==INF || dp[tag][k]==INF) continue; dp[i][j]=Min(dp[i][j],dp[tag][k]+map[k][j]*(n-Count(tag))); } } } // Test(); ans=INF; for (i=0;i<n;i++) { ans=Min(ans,dp[(1<<n)-1][i]); } if (ans==INF) printf("-1/n"); else printf("%d/n",ans); } return 0; }