P4162 [SCOI2009]最长距离

题目链接

这道题数据范围比较小,所以方法还是比较暴力的。

思路:

先按每个格子的状态,让所有格子与他周围的格子连一条权值为它连向那个格子的值(0或1)。然后我们n方枚举所有格子跑最短路,最短路即为从起点到终点的最小障碍数。然后我们枚举所有最短路,先看他移除障碍后是否只用了小于等于k次机会,然后求出两点间的距离,取max即可。

代码如下:

P4162 [SCOI2009]最长距离
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
struct node{
    int nxt,to,val;
}edge[maxn*3];
int head[maxn],cnt;
int num[550][550];
int val[550][550];
char s[550][550];
int n,m,t;
void add(int x,int y,int v){
    edge[++cnt].nxt=head[x];
    edge[cnt].to=y;
    edge[cnt].val=v;
    head[x]=cnt;
}
priority_queue<pair<int ,int> >q;
double dist(int x,int y,int xx,int yy){
    return (double)sqrt((x-xx)*(x-xx)*1.0+(y-yy)*(y-yy)*1.0);
}
double ans;
bool vis[maxn];
int dis[maxn];
void dijkstra(int x){
    memset(dis,88,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[x]=0;
    q.push(make_pair(0,x));
    while(q.size()){
        int u=q.top().second;
        q.pop();
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=head[u];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(dis[v]>dis[u]+edge[i].val){
                dis[v]=dis[u]+edge[i].val;
                q.push(make_pair(-dis[v],v));
            }
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>s[i][j];
            num[i][j]=(i-1)*m+j;
            if(s[i][j]=='1') val[i][j]=1; 
        }
    }
/*    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            printf("%d ",num[i][j]);
        }
        printf("\n");
    }*/
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i>1) add(num[i][j],num[i-1][j],val[i-1][j]);
            if(i<n) add(num[i][j],num[i+1][j],val[i+1][j]);
            if(j>1) add(num[i][j],num[i][j-1],val[i][j-1]);
            if(j<m) add(num[i][j],num[i][j+1],val[i][j+1]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            dijkstra(num[i][j]);
            for(int x=1;x<=n;x++){
                for(int y=1;y<=m;y++){
                    if(dis[num[x][y]]+val[i][j]<=t) ans=max(ans,dist(i,j,x,y));
                }
            }
        }
    }
    printf("%.6lf\n",ans);
    return 0;
}
View Code

 

上一篇:bzoj1297 [SCOI2009]迷路 矩阵快速幂


下一篇:$SCOI2009\ $windy数 数位$dp$