思路:就是找能走的走,遍历一边所有情况,满足就退出。
Accepted | 4284 | 328MS | 2280K | 2239 B | C++ |
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <stdio.h> #include <string.h> #include <cstring> #include <algorithm> #include <vector> #define Maxn 110 #define Maxm 6000 #define LL int #define inf 100000000 #define Abs(a) (a)>0?(a):(-a) using namespace std; int D[Maxn],C[Maxn],dis[Maxn][Maxn],choice[Maxn],n,m,h,vi[Maxn]; void init() { memset(D,0,sizeof(D)); memset(C,0,sizeof(C)); memset(vi,0,sizeof(vi)); for(int i=1;i<=101;i++) for(int j=1;j<=101;j++) dis[i][j]=inf; } void floyd() { int i,j,k; for(i=1;i<=n;i++) dis[i][i]=0; for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]); } int dfs(int u,int leave,int num) { int i,j; if(num==h) { if(dis[u][1]<=leave) return 1; return 0; } for(i=1;i<=h;i++) if(!vi[choice[i]]) { if(leave>=dis[u][choice[i]]+D[choice[i]]) { vi[choice[i]]=1; if(dfs(choice[i],leave-dis[u][choice[i]]-D[choice[i]]+C[choice[i]],num+1)) return 1; vi[choice[i]]=0; } } return 0; } int main() { int i,j,a,b,c,t,money; scanf("%d",&t); while(t--) { init(); scanf("%d%d%d",&n,&m,&money); for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); dis[a][b]=dis[b][a]=c<dis[a][b]?c:dis[a][b]; } floyd(); scanf("%d",&h); for(i=1;i<=h;i++) { scanf("%d%d%d",&a,&b,&c); choice[i]=a,C[a]=b,D[a]=c; } for(i=1;i<=h;i++) { if(!vi[choice[i]]) { if(money>=dis[1][choice[i]]+D[choice[i]]) { vi[choice[i]]=1; if(dfs(choice[i],money-dis[1][choice[i]]-D[choice[i]]+C[choice[i]],1)) break; vi[choice[i]]=0; } } } if(i<=h) printf("YES "); else printf("NO "); } return 0; }