• 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
    ",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
    ",ans);
    68     return 0;
    69 }
  • 相关阅读:
    Office 2007 打开 C# VS2005 导出的Excel时报错:单元格数据太大 Office 2003打开正常 的解决办法
    【30篇突击 android】源码统计 十四
    Android加载对话框,异步执行代码的封装类
    android 图片设置圆角
    【30篇突击 android】源码统计 十二
    android 制作的精美闹钟
    读WP8开发新书,送Windows Phone 8开发书籍
    各种曲线图表。矩形 圆形,股票
    【30篇突击 android】源码统计 十三
    日历程序,支持添加日程提醒
  • 原文地址:https://www.cnblogs.com/Ressed/p/9997142.html
Copyright © 2020-2023  润新知