方法一: 也就是我比赛的时候这么写的...用DP来解旅行商问题...15个城市可以用15位二进制数表示.最大32767...用dp[k][i]表示在k状态下(0~32767)最后到达的是i城市的最大剩余money..
Program:
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<map> #include<queue> #include<stack> #define ll long long #define oo 1000000000 #define pi acos(-1) using namespace std; struct node { int t,c,d; }p[17]; int arc[105][105],n,m,money,goal,dp[70000][17]; void Floyd() { int k,i,j; for (k=1;k<=n;k++) for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (arc[i][k]!=-1 && arc[k][j]!=-1) if (arc[i][j]==-1 || arc[i][j]>arc[i][k]+arc[k][j]) arc[i][j]=arc[i][k]+arc[k][j]; return; } bool EXE_DP() { int i,j,ans,k,h,x,w,data; memset(dp,-1,sizeof(dp)); p[0].t=1; p[0].c=p[0].d=0; w=1; dp[0][0]=money; for (k=1;k<=goal;k++) { h=k; x=1; i=0; while (h) { i++; if (h%2) { w=k-x; for (j=0;j<=n;j++) if (dp[w][j]!=-1 && arc[p[j].t][p[i].t]!=-1) if (dp[w][j]-arc[p[j].t][p[i].t]>=p[i].d) { data=dp[w][j]-arc[p[j].t][p[i].t]+p[i].c-p[i].d; if (dp[k][i]==-1 || dp[k][i]<data) dp[k][i]=data; } } x*=2; h/=2; } } for (i=1;i<=n;i++) if (arc[p[i].t][1]!=-1 && dp[goal][i]!=-1 && dp[goal][i]>=arc[p[i].t][1]) return true; return false; } int main() { // freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int t,x,y,h,w; scanf("%d",&t); while (t--) { memset(arc,-1,sizeof(arc)); scanf("%d%d%d",&n,&m,&money); while (m--) { scanf("%d%d",&x,&y); scanf("%d",&w); if (arc[y][x]==-1 || w<arc[y][x]) arc[x][y]=arc[y][x]=w; } for (x=1;x<=n;x++) arc[x][x]=0; Floyd(); scanf("%d",&h); goal=1; for (x=1;x<=h;x++) { scanf("%d%d%d",&p[x].t,&p[x].c,&p[x].d); goal*=2; } n=h; goal--; if (EXE_DP()) printf("YES\n"); else printf("NO\n"); } return 0; }
Program:
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<map> #include<queue> #include<stack> #define ll long long #define oo 10000000 #define pi acos(-1) using namespace std; struct node { int t,c,d; }p[17]; int arc[105][105],n,m,h; bool used[17]; void Floyd() { int k,i,j; for (k=1;k<=n;k++) for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (arc[i][j]-arc[i][k]>arc[k][j]) arc[i][j]=arc[i][k]+arc[k][j]; return; } bool DFS(int money,int k,int now) { if (k==h) { if (money>=arc[p[now].t][1]) return true; return false; } used[now]=true; for (int i=1;i<=h;i++) if (!used[i] && money-arc[p[now].t][p[i].t]>=p[i].d) if (DFS(money-arc[p[now].t][p[i].t]-p[i].d+p[i].c,k+1,i)) return true; used[now]=false; return false; } int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int t,x,y,w,money; scanf("%d",&t); while (t--) { scanf("%d%d%d",&n,&m,&money); for (y=0;y<=n;y++) for (x=0;x<n;x++) arc[y][x]=arc[x][y]=oo; while (m--) { scanf("%d%d%d",&x,&y,&w); if (w<arc[y][x]) arc[x][y]=arc[y][x]=w; } for (x=1;x<=n;x++) arc[x][x]=0; Floyd(); scanf("%d",&h); for (x=1;x<=h;x++) scanf("%d%d%d",&p[x].t,&p[x].c,&p[x].d); p[0].t=1; p[0].c=p[0].d=0; memset(used,false,sizeof(used)); if (DFS(money,0,0)) printf("YES\n"); else printf("NO\n"); } return 0; }