zoukankan      html  css  js  c++  java
  • 洛谷 P1522 牛的旅行 Cow Tours

    题目链接:https://www.luogu.org/problem/P1522

    思路:编号,然后跑floyd,这是很清楚的。然后记录每个点在这个联通块中的最远距离。

    然后分连通块,枚举两个点(不属于同一个连通块的)建边,计算可能的直径 dist[i] + dist[j] + dis(i,j)。

    当然,这里有一个需要注意,(sccno[x]表示属于哪一个编号的连通块,sccdis[x]表示该连通块的直径),

    在枚举点建边,形成新的牧场,得到新的可能的直径时,dist[i] + dist[j] + dis(i,j) >= max(sccdis[sccno[i]],sccdis[sccno[j]]),

    这个是一定要成立的,因为新的可能的直径不可能小于sccdis[sccno[i]] 和 sccdis[sccno[j]](结合题目意思)。


      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <map>
      7 #include <cmath>
      8 using namespace std;
      9 
     10 typedef long long LL;
     11 #define inf 1e11
     12 #define rep(i, j, k) for (int i = (j); i <= (k); i++)
     13 #define rep__(i, j, k) for (int i = (j); i < (k); i++)
     14 #define per(i, j, k) for (int i = (j); i >= (k); i--)
     15 #define per__(i, j, k) for (int i = (j); i > (k); i--)
     16 
     17 const int N = 160;
     18 int G[N][N];
     19 double f[N][N];
     20 double dist[N];
     21 int sccno[N];
     22 int scccnt;
     23 double sccdis[N];
     24 int scct;
     25 int head[N];
     26 int cnt;
     27 int n;
     28 
     29 struct node{
     30     double x,y;
     31 }po[N];
     32 
     33 struct Edge{
     34     int to;
     35     double w;
     36     int next;
     37 }e[N*N];
     38 
     39 void add(int u,int v,double w){
     40     e[cnt].to = v;
     41     e[cnt].w = w;
     42     e[cnt].next = head[u];
     43     head[u] = cnt++;
     44 }
     45 
     46 inline double dis(node& a,node& b){
     47     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     48 }
     49 
     50 void dfs(int u){
     51     sccno[u] = scccnt;
     52     for(int o = head[u]; ~o; o = e[o].next){
     53         int v = e[o].to;
     54         if(!sccno[v]) dfs(v);
     55     }
     56 }
     57 
     58 int main(){
     59 
     60     scanf("%d",&n);
     61 
     62     //链式前向星
     63     rep(i,1,n) head[i] = -1;
     64     cnt = 0;
     65     
     66     //距离矩阵初始化
     67     rep(i,1,n) rep(j,1,n){
     68         if(i == j) f[i][j] = 0;
     69         else f[i][j] = inf;
     70     }
     71 
     72     //点的输入
     73     rep(i,1,n){
     74         scanf("%lf%lf",&po[i].x,&po[i].y);
     75     }
     76 
     77     //读图
     78     rep(i,1,n){
     79         rep(j,1,n) scanf("%1d",&G[i][j]);
     80     }
     81     
     82     //建边
     83     double way;
     84     rep(i,1,n) rep(j,i+1,n){
     85         if(G[i][j]){
     86             way = dis(po[i],po[j]);
     87             f[j][i] = f[i][j] = way;
     88             add(i,j,way);
     89             add(j,i,way);
     90         }      
     91     }
     92 
     93     //连通图
     94     rep(i,1,n) if(!sccno[i]){
     95         ++scccnt;
     96         dfs(i);
     97     }
     98 
     99 
    100     //最短路
    101     rep(k,1,n) rep(i,1,n) rep(j,1,n){
    102        f[i][j] = min(f[i][j],f[i][k] + f[k][j]);
    103     }
    104 
    105     rep(i,1,n){
    106         rep(j,1,n){
    107             if(f[i][j] == inf) continue;
    108             dist[i] = max(dist[i],f[i][j]);
    109         }
    110     }
    111 
    112     //连通块最长直径
    113     rep(i,1,n){
    114         sccdis[sccno[i]] = max(sccdis[sccno[i]],dist[i]);
    115     }
    116 
    117     double ans_1 = inf;
    118     double tmp;
    119     rep(i,1,n) rep(j,1,n){
    120         if(f[i][j] == inf){
    121             tmp = max(sccdis[sccno[i]],sccdis[sccno[j]]);
    122             ans_1 = min(ans_1,dist[i] + dist[j] + dis(po[i],po[j]));
    123             ans_1 = max(ans_1,tmp);
    124         }
    125     }
    126 
    127     printf("%.6f
    ",ans_1);
    128 
    129     getchar();getchar();
    130     return 0;
    131 }
  • 相关阅读:
    写了这么久前端,你知道浏览器原理吗?
    史上最全的web前端开发程序员学习清单!
    常见前端面试题及答案
    “下辈子再也不当程序员了,我被黑够了”
    什么是web前端,全栈工程师就业前景怎么样?
    要嫁就嫁程序员,钱多话少死得早!
    想转行做web前端工程师,必学这6大技能
    测试用例设计总结
    python读取一个英文文件,并记录每个单词出现的次数,降序输出
    python读取一个文件的每一行判断是否为素数,并把结果写到另一个文件中
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11466901.html
Copyright © 2011-2022 走看看