地址: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 }
时间: 2024-10-06 08:03:32