注意重边,真坑。
裸的TSP
#include <cstdio> #include <iostream> #include<cstring> #include<algorithm> using namespace std; int n,m; int money; int maps[105][105]; int dp[17][1<<17]; void debug(int x,int y) { printf("dp[%d][%d]=%d\n",x,y,dp[x][y]); } int main() { int cas; int a,b,cc,d; scanf("%d",&cas); while(cas--) { scanf("%d%d%d",&n,&m,&money); memset(maps,0x3f,sizeof(maps)); for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&cc); if(cc<maps[a][b])maps[a][b]=maps[b][a]=cc; } for(int i=1;i<=n;i++) maps[i][i]=0; for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { maps[i][j]=min(maps[i][k]+maps[k][j],maps[i][j]); } } } int h; int id[16]; int g[16]; int c[16]; scanf("%d",&h); for(int i=1;i<=h;i++) { scanf("%d%d%d",&a,&b,&d); id[i]=a; c[i]=d; g[i]=b; } memset(dp,-0x3f,sizeof(dp)); int sums=(1<<h); for(int i=1;i<=h;i++) { if(money-maps[1][id[i]]-c[i]>=0) dp[i][1<<(i-1)]=money-maps[1][id[i]]-c[i]+g[i]; } for(int i=1;i<sums;i++) { for(int j=0;j<h;j++) { if((i>>j)&1) { for(int k=0;k<h;k++) { if( ((i>>k)&1) && dp[k+1][i&(~(1<<j))]-maps[id[k+1]][id[j+1]]-c[j+1]>=0) { dp[j+1][i]=max(dp[j+1][i],dp[k+1][i&(~(1<<j))]-maps[id[k+1]][id[j+1]]-c[j+1]+g[j+1]); } } } } } int ok=0; for(int i=1;i<=h;i++) { if(dp[i][sums-1]-maps[id[i]][1]>=0) ok=1; } printf("%s\n",ok?"YES":"NO"); } return 0; }