luogu4162 最长距离 (dijkstra)

相邻格子连双向边,如果一个点有障碍,那进它的边权就是1,否则是0

这样的话,两点间的最短路+[起始点有障碍],就是从一个点走到另一个需要清除的障碍的个数

求出最短路后枚举这两个点就可以了

然而30*30还是太大跑不开floyd,只能写一个dijkstra

 1 #include<bits/stdc++.h>
 2 #define CLR(a,x) memset(a,x,sizeof(a))
 3 using namespace std;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 typedef pair<int,int> pa;
 7 const int maxn=35,npm=905;
 8 
 9 inline ll rd(){
10     ll x=0;char c=getchar();int neg=1;
11     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
12     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
13     return x*neg;
14 }
15 
16 int id[maxn][maxn];
17 int dis[npm][npm];
18 int N,M,T;
19 char can[npm][npm];
20 priority_queue<pa,vector<pa>,greater<pa> > q;
21 bool flag[npm];
22 
23 inline void chkmin(int s,int x,int y){
24     if(dis[s][x]>y)
25         dis[s][x]=y,q.push(make_pair(y,x));
26 }
27 
28 inline void getdis(int s){
29     CLR(dis[s],127);CLR(flag,0);
30     dis[s][s]=0;q.push(make_pair(0,s));
31     while(!q.empty()){
32         int p=q.top().second;q.pop();
33         // printf("~%d %d %d\n",s,p,dis[s][p]);
34         if(flag[p]) continue;flag[p]=1;
35         int i=(p-1)/M+1,j=p%M;if(!j) j=M;
36         if(i<N) chkmin(s,id[i+1][j],dis[s][p]+can[i+1][j]-'0');
37         if(i>1) chkmin(s,id[i-1][j],dis[s][p]+can[i-1][j]-'0');
38         if(j<M) chkmin(s,id[i][j+1],dis[s][p]+can[i][j+1]-'0');
39         if(j>1) chkmin(s,id[i][j-1],dis[s][p]+can[i][j-1]-'0');
40     }
41 }
42 
43 int main(){
44     //freopen("","r",stdin);
45     int i,j,k=0;
46     N=rd(),M=rd(),T=rd();
47     for(i=1;i<=N;i++){
48         scanf("%s",can[i]+1);
49         for(j=1;j<=M;j++)
50             id[i][j]=++k;
51     }
52     for(i=1;i<=N;i++){
53         for(j=1;j<=M;j++){
54             getdis(id[i][j]);
55         }
56     }
57     double ans=0;
58     for(i=1;i<=N;i++){
59         for(j=1;j<=M;j++){
60             for(k=1;k<=N;k++){
61                 for(int l=1;l<=M;l++){
62                     if(dis[id[i][j]][id[k][l]]+can[i][j]-'0'<=T) ans=max(ans,sqrt(0.0+(k-i)*(k-i)+(l-j)*(l-j)));
63                 }
64             }
65         }
66     }
67     printf("%.6lf\n",ans);
68     return 0;
69 }

 

posted @ 2018-11-21 19:40  Ressed  阅读(158)  评论(0编辑  收藏  举报