AcWing 1125. 牛的旅行

原题链接

考察:floyd+枚举

相差了...想的是直径端点作为加的路左右端点之一...但实际是全部枚举.

思路:

        暴力枚举所有没有连通的点,然后对于加的那条路,求左端点的最远距离+右端点的最远距离+加的路线的距离

        最后再与剩下的直径求最小值.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <vector>
 4 #include <cmath>
 5 using namespace std;
 6 const int N = 160,INF = 0x3f3f3f3f;
 7 typedef pair<int,int> PII;
 8 PII p[N];
 9 char mp[N][N];
10 bool st[N];
11 vector<int> v[N];
12 int n,idx,cnt,maxn[N];
13 double dist[N][N],maxd[N];
14 double get(int i,int j)
15 {
16     int x = p[i].first,y = p[i].second;
17     int a = p[j].first,b = p[j].second;
18     return sqrt(1.0*(x-a)*(x-a)+(y-b)*(y-b));
19 }
20 void dfs(int u,int c)
21 {
22     st[u] = 1;
23     v[c].push_back(u);
24     for(int i=1;i<=n;i++)
25       if(mp[u][i]=='1'&&!st[i]) dfs(i,c);
26 }
27 void floyd(int s)
28 {
29     double maxn = 0;
30     for(int k=0;k<v[s].size();k++)
31       for(int i=0;i<v[s].size();i++)
32         for(int j=0;j<v[s].size();j++)
33         {
34             int a = v[s][i],b = v[s][k],c =v[s][j];
35             dist[a][c] = min(dist[a][b]+dist[b][c],dist[a][c]);
36         }
37 }
38 void init()
39 {
40     for(int i=1;i<=n;i++)
41       if(!st[i]) dfs(i,++idx);
42     for(int i=1;i<=idx;i++)
43       for(int j=0;j<v[i].size();j++)
44         for(int k=j+1;k<v[i].size();k++)
45         {
46             int a = v[i][j],b = v[i][k];
47             if(mp[a][b]!='1') continue;
48             dist[a][b] = dist[b][a] = get(a,b);
49         }
50     for(int i=1;i<=idx;i++)
51     {
52         floyd(i);
53         for(int j=0;j<v[i].size();j++)
54           for(int k=0;k<v[i].size();k++)
55           {
56               int a = v[i][j],b = v[i][k];
57               if(dist[a][b]>maxd[a])
58               {
59                   maxd[a] = dist[a][b];//标记与a最远的距离
60                   maxn[a] = b;//与a最远的点
61             }
62           }
63     }
64 }
65 void solve()
66 {
67     double res = INF;
68     for(int i=1;i<=n;i++)
69       for(int j=1;j<=n;j++)
70        if(dist[i][j]==INF)
71        {
72            double d = get(i,j);
73            res = min(res,d+maxd[i]+maxd[j]);
74        }
75     for(int i=1;i<=n;i++) res = max(res,maxd[i]);
76     printf("%.6lf\n",res);
77 }
78 int main()
79 {
80     scanf("%d",&n);
81     for(int i=1;i<=n;i++) scanf("%d%d",&p[i].first,&p[i].second);
82     for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
83     for(int i=1;i<=n;i++)
84       for(int j=1;j<=n;j++)
85         if(i==j) dist[i][j] = 0;
86         else dist[i][j] = INF;
87     init();
88     solve();
89     return 0; 
90 }

 

上一篇:杭电 acm 题目分类


下一篇:numpy study2 1125