最远距离

最远距离


【Description】
whitecloth 有一块矩形土地,被分为N*M 块1*1 的小格子。
有的格子含有障碍物。
如果从格子A 可以走到格子B,那么两个格子的距离就为两个格子中
心的欧几里德距离。
如果从格子A 不可以走到格子B,就没有距离。
如果格子X 和格子Y 有公共边,并且X 和Y 均不含有障碍物,就可
以从X 走到Y。
如果whitecloth 可以移走T 块障碍物,求所有格子间的最大距离。
保证移走T 块障碍物以后,至少有一个格子不含有障碍物。
【Input】
第一行包含三个整数,N M T。
接下来有N 行,每行一个长度为M 的字符串,'0'表示空格子,'1'表
示该格子含有障碍物。
【Output】
一个数表示答案,保留6 位小数
【Sample Input】
3 3 0
001
001
110
【Sample Output】
1.414214
【Hint】
对于20%的数据,满足1 <= N,M <= 30 ,0 <= T <= 0
对于40%的数据,满足1 <= N,M <= 30 ,0 <= T <= 2

把障碍物的权值看做1,求出任意两点间最短距离,之后枚举点对,在最短距离不超过?的前提下更新最大欧几里得距离。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<cmath>
 6 using namespace std;
 7 int n,m,T;
 8 char key;
 9 int map[35*35];
10 int dx[35*35][35*35],head[35*35],cnt;
11 int X[35*35];
12 int Y[35*35];
13 double ans;
14 struct Node{
15     int en,to,val;
16 }eda[55000];
17 bool vis[35*35];
18 void Add(int x,int y,int z){
19     eda[++cnt].en=y;
20     eda[cnt].to=head[x];
21     head[x]=cnt;
22     eda[cnt].val=z;
23 }
24 struct At{
25     int id,dis;
26     bool friend operator < (At a,At b){
27         return a.dis>b.dis;
28     }
29 };
30 void SPFA(int x){
31     dx[x][x]=map[x];
32     vis[x]=1;
33     priority_queue<At>st;
34     At ls;
35     ls.id=x;
36     ls.dis=0;
37     st.push(ls);
38     while(!st.empty()){
39         int u=st.top().id;
40         st.pop();
41         vis[u]=0;
42         for(int i=head[u];i;i=eda[i].to){
43             int y=eda[i].en;
44             if(dx[x][y]>dx[x][u]+eda[i].val){
45             //    if(x==5&&y==7) printf("%d %d %d\n",u,dx[x][u],eda[i].val);
46                 dx[x][y]=dx[x][u]+eda[i].val;
47                 if(!vis[y]){
48                     vis[y]=0;
49                     ls.id=y;
50                     ls.dis=dx[x][y];
51                     st.push(ls);
52                 }
53             }
54         }
55     }
56 }
57 int main(){
58     memset(dx,30,sizeof(dx));
59     scanf("%d%d%d",&n,&m,&T);
60     for(int i=1;i<=n;i++){
61         for(int j=1;j<=m;j++){
62             cin>>key;
63             if(key=='1') map[(i-1)*m+j]=1;
64             X[(i-1)*m+j]=i;
65             Y[(i-1)*m+j]=j;
66         }
67     }
68     for(int i=1;i<=n*m;i++){
69         if(i%m!=1){
70             Add(i,i-1,map[i-1]);
71         }
72         if(i%m!=0){
73             Add(i,i+1,map[i+1]);
74         }
75         if(i>m){
76             Add(i,i-m,map[i-m]);
77         }
78         if(i<(n-1)*m){
79             Add(i,i+m,map[i+m]);
80         }
81     }
82     for(int i=1;i<=n*m;i++){
83         SPFA(i);
84     }
85     for(int i=1;i<=n*m;i++){
86         for(int j=i+1;j<=n*m;j++){
87             if(dx[i][j]<=T){//printf("dx[%d][%d]= %d\n",i,j,dx[i][j]);
88                 if(ans<sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j])))
89                     ans=sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]));
90             }
91         }
92     }
93     printf("%.6lf",ans);
94 }
View Code

 

posted @ 2015-10-11 18:34 Lenicodes 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值