1295: [SCOI2009]最长距离

链接

思路

  每次选两个点,spfa,到每个点需要搬多少石头,再枚举两个点,判断是否可以在搬得石头的个数小于t的情况下,走到,取最大值。

  zz的我,spfa都不会写了。。。

代码

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 
 7 using namespace std;
 8 
 9 const int N = 35;
10 const int INF = 1e9;
11 
12 char s[N][N];
13 int mp[N][N],dis[N][N],q[100100];
14 bool vis[N][N];
15 int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
16 int n,m,t,L,R;
17 
18 #define getid(x,y) (x-1)*n+y
19 #define getx(z) (z-1)/n+1
20 #define gety(z) ((z%m)==0)?m:(z%m)
21 
22 void bfs(int a,int b) {
23     for (int i=1; i<=n; ++i) 
24         for (int j=1; j<=m; ++j) dis[i][j] = INF,vis[i][j] = false;
25     dis[a][b] = mp[a][b];
26     vis[a][b] = true;
27     L = 1,R = 0;
28     q[++R] = getid(a,b);
29     while (L <= R) {
30         int x = getx(q[L]),y = gety(q[L]);L++;//潜在bug不可以gety(q[L++]);
31         for (int i=0; i<4; ++i) {
32             int xx = x + dx[i],yy = y + dy[i];
33             if (xx < 1 || xx > n || yy > m || yy < 1) continue;
34             if (dis[xx][yy] <= dis[x][y] + mp[xx][yy]) continue;
35             dis[xx][yy] = dis[x][y] + mp[xx][yy];
36             q[++R] = getid(xx,yy);
37             vis[xx][yy] = true;
38         }
39         vis[x][y] = false;
40     }
41 }
42 
43 int main() {
44     cin >> n >> m >> t;
45     for (int i=1; i<=n; ++i) {
46         scanf("%s",s[i]+1);
47     }
48     for (int i=1; i<=n; ++i) 
49         for (int j=1; j<=m; ++j) 
50             mp[i][j] = s[i][j]=='1';
51     double ans = 0;
52     for (int a=1; a<=n; ++a) {
53         for (int b=1; b<=m; ++b) {
54             bfs(a,b);
55             for (int c=1; c<=n; ++c) // 也是从1开始 
56                 for (int d=1; d<=m; ++d) // 
57                     if (mp[a][b] + dis[c][d] <= t) 
58                         ans = max(ans,sqrt(1.0*(a-c)*(a-c)+1.0*(b-d)*(b-d)));
59         }
60     }
61     printf("%.6lf",ans);    
62     return 0;
63 }

 

posted @ 2018-04-17 15:24  MJT12044  阅读(146)  评论(0编辑  收藏  举报