zoukankan      html  css  js  c++  java
  • P4162 [SCOI2009]最长距离

    题目链接

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

    思路:

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

    代码如下:

    #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("
    ");
        }*/
        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
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Exe4j 打包: this executable was created with an evaluation version of exe4j
    使用fidder对安卓模拟器进行抓包
    PowerMock学习(八)之Mock Argument Matcher的使用
    PowerMock学习(七)之Mock Constructor的使用
    adb devices无法连接mumu模拟器
    PowerMock学习(六)之Mock Final的使用
    PowerMock学习(五)之Verifying的使用
    PowerMock学习(四)之Mock static的使用
    KMP(Knuth-Morris-Pratt)算法
    并查集-连通性问题
  • 原文地址:https://www.cnblogs.com/LJB666/p/11628193.html
Copyright © 2011-2022 走看看