• [ SCOI 2009 ] 最长距离


    (\)

    (Description)


    一个(N imes M)的网格图中有一些坏点,图是四联通的。

    你至多可以拿走(K)个坏点,求拿走后联通的点对中欧几里得距离最大是多少。

    • (N,Min [0,30])(Kin [0,30])

    (\)

    (Solution)


    • 设进入一个坏点代价为(1),进入其他点的代价为(0)建图,对每个点跑单源最短路。

    • 距离(le K)的点就代表可以通过移除坏点到达,枚举一遍所有点判断然后更新即可。

    (\)

    (Code)


    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 40
    #define M 1010
    #define R register
    #define gc getchar
    using namespace std;
    typedef long long ll;
    
    double ans;
    bool val[N][N],vis[M];
    ll n,m,t,tot,cnt,num[N][N],hd[M],dis[M];
    
    struct edge{int to,nxt,w;}e[M<<2];
    
    inline void add(int u,int v,int w){
      e[++tot].to=v; e[tot].w=w;
      e[tot].nxt=hd[u]; hd[u]=tot;
    }
    
    inline int rd(){
      int x=0; bool f=0; char c=gc();
      while(!isdigit(c)){if(c=='-')f=1;c=gc();}
      while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
      return f?-x:x;
    }
    
    inline void init(){
      n=rd(); m=rd(); t=rd();
      for(R int i=1;i<=n;++i){
        char c=gc();
        while(!isdigit(c)) c=gc();
        num[i][1]=++cnt;
        val[i][1]=(c=='1');
        for(R int j=2;j<=m;++j){
          num[i][j]=++cnt;
          val[i][j]=(gc()=='1');
        }
      }
      for(R int i=1;i<=n;++i)
        for(R 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]);
        }
    }
    
    inline double dist(int x1,int y1,int x2,int y2){
      return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    
    priority_queue<pair<int,int> > q;
    inline void dij(int x){
      memset(vis,0,sizeof(vis));
      memset(dis,0x3f,sizeof(dis));
      dis[x]=0;
      q.push(make_pair(0,x));
      while(!q.empty()){
        int u=q.top().second; q.pop();
        if(vis[u]) continue; vis[u]=1;
        for(R int i=hd[u],v;i;i=e[i].nxt)
          if(dis[v=e[i].to]>dis[u]+e[i].w){
            dis[v]=dis[u]+e[i].w;
            q.push(make_pair(-dis[v],v));
          }
      }
    }
    
    int main(){
      init();
      for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j){
          dij(num[i][j]);
          for(R int x=1;x<=n;++x)
            for(R int y=1;y<=m;++y)
              if(dis[num[x][y]]<=t-val[i][j]) ans=max(ans,dist(i,j,x,y));
        }
      printf("%lf
    ",ans);
      return 0;
    }
    
    
  • 相关阅读:
    clr via c# 定制特性
    clr via c# delegate
    clr via c# Array2
    clr from c# 字符 ,字符串 和 文本处理
    clr via c# 接口
    clr via c# 泛型
    clr via c# 事件
    clr via c# 参数和属性
    程序设计入门——C语言 第6周编程练习 2 完数(5分)
    程序设计入门——C语言 第6周编程练习 1 分解质因数(5分)
  • 原文地址:https://www.cnblogs.com/SGCollin/p/9640162.html
Copyright © 2020-2023  润新知