【最短路】【图论】【Floyed】牛的旅行(ssl 1119/luogu 1522)
生活随笔
收集整理的這篇文章主要介紹了
【最短路】【图论】【Floyed】牛的旅行(ssl 1119/luogu 1522)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
牛的旅行
ssl 1119
luogu 1522
題目大意
有兩堆點(diǎn),每一堆點(diǎn)之中的任何兩個點(diǎn)都一定有相連的路線,連接兩堆點(diǎn)中的各一個點(diǎn),使最遠(yuǎn)的兩個點(diǎn)的距離最短
原題
農(nóng)民John的農(nóng)場里有很多牧區(qū)。有的路徑連接一些特定的牧區(qū)。一片所有連通的牧區(qū)稱為一個牧場。但是就目前而言,你能看到至少有兩個牧區(qū)不連通。這樣,農(nóng)民John就有多個牧區(qū)了。
John想在農(nóng)場里添加一條路徑(注意,恰好一條)。對這條路徑有以下限制:
一個牧場的直徑就是牧場中最遠(yuǎn)的兩個牧區(qū)的距離(本題中所提到的所有距離指的都是最短的距離)。考慮如下的有5個牧區(qū)的牧場,牧區(qū)用星號表示,路徑用直線表示。每一個牧區(qū)都有自己的坐標(biāo):
這個牧場的直徑大約是12.07106,最遠(yuǎn)的兩個牧區(qū)是A和E,它們之間的最短路徑是A-B-E。
這里是另一個牧場:
這兩個牧場都在John的農(nóng)場上。John將會在兩個牧場中各選一個牧區(qū),然后用一條路徑連起來,使得連通后這個新的更大的牧場有最小的直徑。
注意,如果兩條路徑中途相交,我們不認(rèn)為它們是連通的。只有兩條路徑在同一個牧區(qū)相交,我們才認(rèn)為它們是連通的。
輸入文件包括牧區(qū)、它們各自的坐標(biāo),還有一個如下的對稱鄰接矩陣:
A B C D E F G H
A 0 1 0 0 0 0 0 0
B 1 0 1 1 1 0 0 0
C 0 1 0 0 1 0 0 0
D 0 1 0 0 1 0 0 0
E 0 1 1 1 0 0 0 0
F 0 0 0 0 0 0 1 0
G 0 0 0 0 0 1 0 1
H 0 0 0 0 0 0 1 0
輸入文件至少包括兩個不連通的牧區(qū)。
請編程找出一條連接兩個不同牧場的路徑,使得連上這條路徑后,這個更大的新牧場有最小的直徑。
Input
第1行: 一個整數(shù)N (1 <= N <= 150), 表示牧區(qū)數(shù)
第2到N+1行: 每行兩個整數(shù)X,Y (0 <= X ,Y<= 100000), 表示N個牧區(qū)的坐標(biāo)。注意每個 牧區(qū)的坐標(biāo)都是不一樣的。
第N+2行到第2*N+1行: 每行包括N個數(shù)字(0或1) 表示如上文描述的對稱鄰接矩陣。
Output
只有一行,包括一個實(shí)數(shù),表示所求答案。數(shù)字保留六位小數(shù)。
Sample Input
8
10 10
15 10
20 10
15 15
20 15
30 15
25 10
30 10
01000000
10111000
01001000
01001000
01110000
00000010
00000101
00000010
Sample Output
22.071068
解題方法:
先求出兩個區(qū)塊的最短路,再求出每個區(qū)塊中每個點(diǎn)與相距此點(diǎn)最大的點(diǎn)的距離,枚舉兩邊的所有點(diǎn),將任意兩個點(diǎn)(不同區(qū)域)連接后的的結(jié)果就是兩個點(diǎn)的距離加上兩個點(diǎn)在本區(qū)域的相差最大的距離(若不懂,看代碼)
注意:
當(dāng)出現(xiàn)下圖時(推薦按住左鍵再移動來放大圖片),要連接3和4,但最大長度不是1-3-4或2-3-4,而是1-2,所以要注意
#include<cstdio> #include<cmath> #include<iostream> #include<cstring> #include<algorithm> #include<string> using namespace std; int n; double f[152][152],b[152],jl[152][152],ans,g,sum; char t; struct rec {int x,y; }a[152]; int main() {scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d %d",&a[i].x,&a[i].y);memset(f,0x7f,sizeof(f));//初值memset(jl,0x7f,sizeof(jl));g=f[0][0];//記錄最大值for (int i=1;i<=n;i++){getchar();//換行for (int j=1;j<=n;j++){t=getchar();//輸入jl[i][j]=sqrt(double((a[i].x-a[j].x)*(a[i].x-a[j].x))+double((a[i].y-a[j].y)*(a[i].y-a[j].y)));//用勾股定理求距離if (t=='1') f[i][j]=jl[i][j];//f用來求最短路}}for (int k=1;k<=n;k++)for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if ((i!=j)&&(j!=k)&&(k!=i)&&(f[i][k]+f[k][j]<f[i][j]))f[i][j]=min(f[i][k]+f[k][j],f[i][j]);//求最短路for (int i=1;i<=n;i++){for (int j=1;j<=n;j++)if (f[i][j]!=g)b[i]=max(f[i][j],b[i]);//求距離最長的sum=max(sum,b[i]);//記錄}ans=g;for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if ((f[i][j]==g)&&(i!=j))//要不同區(qū)ans=min(ans,b[i]+b[j]+jl[i][j]);//連接printf("%.6lf",max(ans,sum));//輸出最大的return 0; }溫馨提示:
在luogu中要用scanf("%s")來一行一行地輸入字符數(shù)組
總結(jié)
以上是生活随笔為你收集整理的【最短路】【图论】【Floyed】牛的旅行(ssl 1119/luogu 1522)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 万能的打印文档设置Word文档打印设置
- 下一篇: 【图论】【最短路】【Dijkstra】最