码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ2845 旅游规划

时间:2018-10-05 16:15:27      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:eof   比较   bit   ack   display   处理   hid   lse   int   

技术分享图片

样例

技术分享图片
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
输入1
技术分享图片
 3 
输出1
技术分享图片
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
输入2
技术分享图片
impossible
输出2

思路

状压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 旅游规划

标签:eof   比较   bit   ack   display   处理   hid   lse   int   

原文地址:https://www.cnblogs.com/GREED-VI/p/9744915.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!