cdoj1588 潘爷泡妹

地址:http://acm.uestc.edu.cn/#/problem/show/1588

题目:复制过来发现有问题,自己去cdoj看吧

 

思路:

  1.先进行多次spfa跑出所有人之间的相互到达所需要的步数。

  2.知道所有人之间的距离关系后,就是个从初始点出发泡q个妹子所需要的最少花费问题。

  这时你可以全排列求解:O(q!)

  或者状压dp:dp[s][x]可以转移到dp[s|(1<<k)],x可到达k。时间复杂度O((q^2)*(2^q));

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define MP make_pair
 6 #define PB push_back
 7 typedef long long LL;
 8 typedef pair<int,int> PII;
 9 const double eps=1e-8;
10 const double pi=acos(-1.0);
11 const int K=1e6+7;
12 const int mod=554056561;
13 
14 
15 struct node
16 {
17     int x,y,v;
18     node(){}
19     node(int a,int b,int c){x=a,y=b,v=c;}
20 }gg[10];
21 int d[100][100],dp[1<<10][10];
22 int n,m,s,q,dis[100][100],inque[100][100];
23 int dx[]={-2,-2,-1,-1,1,1,2,2};
24 int dy[]={-1,1,-2,2,-2,2,-1,1};
25 
26 void bfs(node &ta)
27 {
28     queue<node>q;
29     memset(dis,0x3f3f3f3f,sizeof dis);
30     memset(inque,0,sizeof inque);
31     q.push(ta),dis[ta.x][ta.y]=0,inque[ta.x][ta.y]=1;
32     while(q.size())
33     {
34         node x=q.front();
35         q.pop(),inque[x.x][x.y]=0;
36         for(int i=0;i<8;i++)
37         {
38             int nx=x.x+dx[i],ny=x.y+dy[i];
39             if(!(nx>=1 && ny>=1 && nx<=n && ny<=m))
40                 continue;
41             if(dis[nx][ny]>dis[x.x][x.y]+abs(dx[i]))
42             {
43                 dis[nx][ny]=dis[x.x][x.y]+abs(dx[i]);
44                 if(!inque[nx][ny])
45                     q.push(node(nx,ny,0)),inque[nx][ny]=1;
46             }
47         }
48     }
49 }
50 int main(void)
51 {
52     std::ios::sync_with_stdio(false);
53     std::cin.tie(0);
54     int t;
55     cin>>t;
56     while(t--)
57     {
58         int ans=0x3f3f3f3f;
59         cin>>n>>m>>s>>q>>gg[0].x>>gg[0].y;
60         for(int i=1; i<=s; i++)
61             cin>>gg[i].x>>gg[i].y>>gg[i].v;
62         for(int i=0;i<=s;i++)
63         {
64             bfs(gg[i]);
65             for(int j=0;j<=s;j++)
66                 d[i][j]=dis[gg[j].x][gg[j].y];
67             //printf("d[%d][%d]:%d\n",i,j,d[i][j]);
68         }
69         memset(dp,0x3f3f3f3f,sizeof dp);
70         for(int i=1;i<=s;i++)
71             dp[1<<(i-1)][i]=d[0][i]+gg[i].v;
72         for(int i=0,sz=(1<<s);i<sz;i++)
73         {
74             for(int j=0;j<s;j++)
75             for(int k=0;k<s;k++)
76             if(((1<<j)^i) && ((1<<k)&i))
77                 dp[i|(1<<j)][j+1]=min(dp[i][k+1]+d[k+1][j+1]+gg[j+1].v,dp[i|(1<<j)][j+1]);
78         }
79         for(int i=0,sz=(1<<s);i<sz;i++)
80         for(int j=1;j<=s;j++)
81         {
82             int sum=0;
83             for(int k=0;k<s;k++)
84             if(i&(1<<k)) sum++;
85             if(sum==q)ans=min(ans,dp[i][j]);
86         }
87         if(ans>=0x3f3f3f3f)
88             ans=-1;
89         cout<<ans<<"\n";
90     }
91     return 0;
92 }

 

posted @ 2017-05-17 22:34  weeping  阅读(234)  评论(0编辑  收藏  举报