hdu 4284——Travel
2015-07-25 19:40
381 查看
题意:一个国家有最多200个城市。一个人住在城市1,他想去其中15个城市打工。每次打工先要交手续费,然后才能挣一些钱。从一个城市到另一个城市需要花一定路费。问这个人能否从1城市出发把他所有想打工的城市都打一遍工,然后回到1.
思路:最多15个城市,所以可以考虑状态压缩。先把15个城市之间两两距离预处理出来。然后每到达一个城市把状态中这个城市对应的位置变成1。
我用的是队列来辅助状态转移。
最开始做这道题的时候一直超时,后来把队列弄成全局变量就变成了re。看来最好还是不要把队列弄成全局变量。改回来以后还是超时。跟别人的代码对比了一下,发现是状态转移写的太冗余了。
假设到达其中一个城市i的状态是s,我考虑了从i走向其他城市,不在那个城市打工,仅仅路过这种情况。事实上这种情况是不用考虑的,考虑路过这种情况仅仅是在不知道每两个点之间最短距离的时候用。但是预处理中已经把两两之间最短距离求出来了,所以这样的考虑完全不需要,只是浪费时间。
因为超时怀疑是标准库效率不高,还自己实现了一个队列。。。
代码如下:
思路:最多15个城市,所以可以考虑状态压缩。先把15个城市之间两两距离预处理出来。然后每到达一个城市把状态中这个城市对应的位置变成1。
我用的是队列来辅助状态转移。
最开始做这道题的时候一直超时,后来把队列弄成全局变量就变成了re。看来最好还是不要把队列弄成全局变量。改回来以后还是超时。跟别人的代码对比了一下,发现是状态转移写的太冗余了。
假设到达其中一个城市i的状态是s,我考虑了从i走向其他城市,不在那个城市打工,仅仅路过这种情况。事实上这种情况是不用考虑的,考虑路过这种情况仅仅是在不知道每两个点之间最短距离的时候用。但是预处理中已经把两两之间最短距离求出来了,所以这样的考虑完全不需要,只是浪费时间。
因为超时怀疑是标准库效率不高,还自己实现了一个队列。。。
代码如下:
[code]#include<cstdio> #include<cstdlib> #include<math.h> #include<iostream> #include<cstring> #include<map> #include<set> #include<list> #include<stack> #include<algorithm> #include<queue> #include<vector> #include<time.h> using namespace std; const int inf = 100000000; int id[200]; int ci[200]; int di[200]; int icity[20]; int dp[20][1<<17]; int dis[200][200]; bool in[20][1<<17]; struct STA{ int city; int s; STA(int _c = 0,int _s = 0):city(_c),s(_s){} }; void Floyd(int n) { for(int i = 1;i<=n;++i){ dis[i][i]=0; } for(int k = 1;k<=n;++k){ for(int i=1;i<=n;++i){ if(dis[i][k]==inf)continue; for(int j=1;j<=n;++j){ if(dis[k][j]<inf) dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]); } } } } struct que { int maxsize ; STA q[1000000]; int front; int rear; int size; que() { front = rear = 0; size = 0; maxsize = 999999; } void clear() { front = rear = 0; size = 0; } void push(STA a) { q[rear] = a; rear ++; rear%=maxsize; size ++; } STA pop() { STA ret = q[front]; front++; front%= maxsize; size--; return ret; } bool empty() { return size == 0 ; } }; que q; bool solve(int &money,int &h) { // queue<STA> q; q.clear(); memset(in,0,sizeof(in)); memset(dp,-1,sizeof(dp)); q.push(STA(1,0)); dp[id[1]][0]=money; in[id[1]][0]=1; if(money>ci[1]){ dp[id[1]][1<<id[1]] = money - ci[1]+di[1];q.push(STA(1,1<<id[1])); in[id[1]][1<<id[1]] = 1; } //++++++++++++++++++++++++++++参考http://blog.csdn.net/acm_cxlove/article/details/7963286 // for(int i = 0 ;i< (1<<h);++i){ // for(int j = 0 ;j<h;++j){ // if(dp[j][i]<0)continue; // for(int k = 0;k<h;++k){ // if(k==j||((1<<k)&i)) continue; // if(dp[j][i]>=dis[icity[j]][icity[k]]+ci[icity[k]]) // dp[k][i|(1<<k)]=max(dp[k][i|(1<<k)],dp[j][i]-dis[icity[j]][icity[k]]-ci[icity[k]]+di[icity[k]]); // } // } // } // // bool ans=false; // for(int i=0;i<h;i++) // //最后判断能不能返回起点 // if(dp[i][(1<<h)-1]>=dis[icity[i]][1]){ // ans=true; // break; // } // return ans?1:0; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ while(!q.empty()){ STA f = q.pop(); // q.pop(); int u = f.city; in[id[u]][f.s]=0; int st = f.s; int idu = id[u]; for(int idv = 0; idv < h;++idv){ if(idv == idu)continue; int v = icity[idv]; if(dis[u][v] == inf)continue; if(dp[idu][st] < dis[u][v])continue; int tst = (st | (1<<idv)); if(tst == st)continue; if(dp[idu][st] < ci[v]+dis[u][v])continue; if(dp[idv][tst] < dp[idu][st]-ci[v]-dis[u][v]+di[v]){ dp[idv][tst] = dp[idu][st]-ci[v]-dis[u][v]+di[v]; if(!in[idv][tst]){ q.push(STA(v,tst));in[idv][tst] = 1; } if(v == 1 && tst == (1<<h)-1)return true; } } } bool ans=false; for(int i=0;i<h;i++) if(dp[i][(1<<h)-1]>=dis[icity[i]][1]){ ans=true; break; } return ans?1:0; } int main() { // freopen("data.txt","r",stdin); int T; scanf("%d",&T); while(T--){ int n,m,money;int h; scanf("%d%d%d",&n,&m,&money); for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ dis[i][j]=inf; } } for(int i=0;i<m;++i){ int u,v,w; scanf("%d%d%d",&u,&v,&w); if(dis[u][v]>w){ dis[u][v] = w; dis[v][u] = w; } } scanf("%d",&h); memset(id,-1,sizeof(id)); memset(ci,0,sizeof(ci)); memset(di,0,sizeof(di)); for(int i=0;i<h;++i){ int t,c,d; scanf("%d%d%d",&t,&c,&d); id[t]=i; icity[i]=t; di[t]=c; ci[t]=d; } if(id[1]<0){ id[1]=h; icity[h++]=1; } Floyd(n); if(solve(money,h))puts("YES"); else puts("NO"); } return 0; }
相关文章推荐
- 面向对象2
- Struts2的配置文件——web.xml
- 编程领域感悟
- xcode调试命令
- java之可变参数
- 与阿根廷一起学习Java Web四个发展:对于信息传输和信息传输
- ECharts学习总结(五):echarts的Option概览
- java之可变参数
- 面向对象1
- 一道小小的内存申请面试题
- bloom filter
- 深入剖析Android四大组件(一)——Activity生命周期详解
- ECharts学习总结(四):echarts的实例方法
- Problem A CodeForces 560A
- 文件操作---沙盒路径
- 两个堆栈实现一个队列和一叠两个队列实现【算法导论课后题】
- Sql Server查询性能优化之创建合理的索引(下篇)
- OC_协议
- 模板技术-freemarker与velocity
- 关于Android四大组件的学习总结