标签:
题意:给你一些N个点,M条边,走每条边要花费金钱,然后给出其中必须访问的点,在这些点可以打工,但是需要先拿到证书,只可以打一次,也可以选择不打工之直接经过它。一个人从1号点出发,给出初始金钱,问你能不能访问所以的点,并且获得所以证书。
题解:目标是那些一定要访问的点,怎么到达的我们不关心,但是我们关系花费最少的路径,而且到达那个点后是一定要打工的,如果只是经过,那么在求花费最少的路径的时候已经考虑过了。
因此先用Folyd求出各个点直接的最短路径,由于N很小,又只要求出一个解,所以直接dfs暴搜就行了。
M很大,可能有重边。注意处理。
当时一看,图论题,没仔细想就跳过了。下面的代码加了输入挂,因为第一遍写T了,以为是输入问题,所以加上了。改了我好几个小时没过,重写一遍就过了。
#define HDU #ifndef HDU #include<bits/stdc++.h> #else //pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<set> #include<algorithm> //#include<iostream> #endif // HDU #define mins(s,x) if((x)<(s)) s = x #define maxs(s,x) if((x)>(s)) s = x using namespace std; typedef long double ld; typedef long long ll; const int maxn = 105; const int maxh = 20; const int INF = 0x3f3f3f3f; int N,M,Mon,H; int dis[maxn][maxn]; inline void scan_d(int &ret) { char c;ret=0; while((c=getchar())<‘0‘||c>‘9‘); while(c>=‘0‘&&c<=‘9‘) ret=ret*10+(c-‘0‘),c=getchar(); } struct City { int cost,earn,id; void input(){ scanf("%d%d%d",&id,&earn,&cost); } }city[maxh]; bool vis[maxh]; bool dfs(int u,int money,int cnt) { if( cnt == H && money >= dis[u][1] )return true; for(int i = 0; i < H; i++) if(!vis[i]){ int v = city[i].id; if( money >= dis[u][v]+city[i].cost ){ vis[i] = 1; if(dfs(v,money-dis[u][v]-city[i].cost+city[i].earn,cnt+1)) return true; vis[i] = 0; } } return false; } void init() { memset(vis,false,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); for(int i = 1; i <= N; i++) dis[i][i]= 0; } //#define local int main() { #ifdef local freopen("in.txt","r",stdin); // freopen("myout.txt","w",stdout); #endif // local int T; scan_d(T); //scanf("%d",&T); while(T--){ scan_d(N);scan_d(M);scan_d(Mon); //scanf("%d%d%d",&N,&M,&Mon); init(); for(int i = 0; i < M; i++){ int u,v,w; scan_d(u);scan_d(v);scan_d(w); //scanf("%d%d%d",&u,&v,&w); //if(u == v) continue; if(dis[u][v]>w) { dis[u][v] = w; dis[v][u] = dis[u][v]; } } for(int k = 1; k <= N; k++) for(int i = 1; i <= N; i++){ if(dis[i][k]<INF) for(int j = 1; j <= N; j++) { mins(dis[i][j],dis[i][k]+dis[k][j]); } } scanf("%d",&H); for(int i = 0; i < H; i++){ city[i].input(); } printf("%s\n",dfs(1,Mon,0)?"YES":"NO"); } return 0; }
HDU 4284 Travel Folyd预处理+dfs暴搜
标签:
原文地址:http://www.cnblogs.com/jerryRey/p/4665683.html