ZOJ2845 旅游规划
Posted greed-vi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ2845 旅游规划相关的知识,希望对你有一定的参考价值。
样例
3 3 3 1 2 3 10 8 6 1 2 120 0 1 3 60 1 2 3 50 1 0 0 0 0
3
3 3 2 1 2 3 10 8 6 1 2 120 0 1 3 60 1 2 3 50 1 0 0 0 0
impossible
思路
状压DP,一开始把必须要去的点压成一个数(must|=1<<(v-1);),然后预处理每个状态,s数组表示每个状态里有多少个1(走到点数),然后跑一遍FLOYD,做一下状压DP
具体就是从比这个状态少一个1(如0110-->0111)的状态过来并比较一下所花时间多少(if (!(i&(1<<(k-1)))) f[i|(1<<(k-1))][k]=min(f[i|(1<<(k-1))][k],(double)((double)f[i][j]+(double)dis[j][k]+(double)t[k]));),最后比较一下s[i]最大值(如果当前状态不包含must i&must==must,不要,如果超时,不要)
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,must=0,ans=-1,s[1<<15]; 4 double d[20][20],f[1<<15][20],t[20],dis[20][20],tim; 5 void FLOYD() 6 { 7 for (int k=1;k<=n;k++) 8 for (int i=1;i<=n;i++) 9 for (int j=1;j<=n;j++) 10 dis[i][j]=min(dis[i][j],(double)dis[i][k]+dis[k][j]); 11 for (int i=1;i<=n;i++) dis[i][i]=0; 12 // for (int i=1;i<=n;i++) 13 // { 14 // for (int j=1;j<=n;j++) 15 // cout<<i<<" to "<<j<<" is "<<dis[i][j]<<endl; 16 // } 17 } 18 void init() 19 { 20 freopen("travel.in","r",stdin); 21 freopen("travel.out","w",stdout); 22 memset(dis,0x7f,sizeof(dis)); 23 cin>>n>>m>>tim; 24 tim*=12.0; 25 for (int i=1;i<=m;i++) 26 { 27 int v; 28 cin>>v; 29 must|=1<<(v-1); 30 } 31 for (int i=0;i<=(1<<n)-1;i++) for (int j=1;j<=n;j++) if (i&(1<<(j-1))) s[i]++; 32 //cout<<must<<endl; 33 for (int i=1;i<=n;i++) cin>>t[i]; 34 int x,y,len,kind; 35 while(1) 36 { 37 cin>>x>>y>>len>>kind; 38 if (x==0&&y==0&&len==0&&kind==0) break; 39 if (kind==1) dis[x][y]=dis[y][x]=(double)len/120.0; 40 if (kind==0) dis[x][y]=dis[y][x]=(double)len/80.0; 41 } 42 } 43 void dp() 44 { 45 for(int i=0;i<=(1<<n)-1;i++) for(int j=1;j<=n;j++) f[i][j]=2e9; 46 f[0][1]=0; 47 for (int i=0;i<=(1<<n)-1;i++) 48 { 49 for (int j=1;j<=n;j++) 50 if (f[i][j]!=2e9) 51 { 52 for (int k=1;k<=n;k++) 53 if (!(i&(1<<(k-1)))) 54 f[i|(1<<(k-1))][k]=min(f[i|(1<<(k-1))][k],(double)((double)f[i][j]+(double)dis[j][k]+(double)t[k])); 55 } 56 } 57 } 58 void out() 59 { 60 for (int i=0;i<=(1<<n)-1;i++) 61 { 62 for (int j=1;j<=n;j++) 63 cout<<f[i][j]<<" "; 64 cout<<endl; 65 } 66 cout<<endl; 67 for (int i=1;i<=n;i++) 68 { 69 for (int j=1;j<=n;j++) 70 cout<<dis[i][j]<<" "; 71 cout<<endl; 72 } 73 } 74 int main(){ 75 init(); 76 FLOYD(); 77 dp(); 78 //out(); 79 for (int i=0;i<=(1<<n)-1;i++) 80 if ((i&must)==must) for (int j=1;j<=n;j++)if (f[i][j]+dis[j][1]<=(double)tim) ans=max(ans,s[i]); 81 if (ans!=-1) cout<<ans<<endl;else cout<<"impossible"<<endl; 82 return 0; 83 } 84 /* 85 3 3 3 86 1 2 3 87 10 8 6 88 1 2 120 0 89 1 3 60 1 90 2 3 50 1 91 0 0 0 0 92 93 3 3 2 94 1 2 3 95 10 8 6 96 1 2 120 0 97 1 3 60 1 98 2 3 50 1 99 0 0 0 0 100 */
以上是关于ZOJ2845 旅游规划的主要内容,如果未能解决你的问题,请参考以下文章
假期训练七(hdu-2845 dp,hdu-1846,2188 巴什博奕)
图论(网络流,分数规划):COGS 2047. [ZOJ2676]网络战争