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 }
标签:旅行,dist,int,double,1125,枚举,端点,include,AcWing 来源: https://www.cnblogs.com/newblg/p/14723708.html