牛的旅行 題解

2021-10-01 18:46:08 字數 3635 閱讀 5405

農民joh

njohn

john

的農場裡有很多牧區。有的路徑連線一些特定的牧區。一片所有連通的牧區稱為乙個牧場。但是就目前而言,你能看到至少有兩個牧區不連通。這樣,農民joh

njohn

john

就有多個牧區了。

j oh

njohn

john

想在農場裡新增一條路徑(注意,恰好一條)。對這條路徑有以下限制:

乙個牧場的直徑就是牧場中最遠的兩個牧區的距離 ( 本題中所提到的所有距離指的都是最短的距離 ) 。考慮如下的有5個牧區的牧場,牧區用「∗」

「*」「∗

」表示,路徑用直線表示。每乙個牧區都有自己的座標:

這個牧場的直徑大約是12.07106, 最遠的兩個牧區是a

aa和e

ee,它們之間的最短路徑是a−b

−ea-b-e

a−b−e。

這裡是另乙個牧場:

這兩個牧場都在john的農場上。john將會在兩個牧場中各選乙個牧區,然後用一條路徑連起來,使得連通後這個新的更大的牧場有最小的直徑。

注意,如果兩條路徑中途相交,我們不認為它們是連通的。只有兩條路徑在同乙個牧區相交,我們才認為它們是連通的。

輸入檔案包括牧區、它們各自的座標,還有乙個如下的對稱鄰接矩陣:

0 1 0 0 0 0 0 0

1 0 1 1 1 0 0 0

0 1 0 0 1 0 0 0

0 1 0 0 1 0 0 0

0 1 1 1 0 0 0 0

0 0 0 0 0 0 1 0

0 0 0 0 0 1 0 1

0 0 0 0 0 0 1 0

輸入檔案至少包括兩個不連通的牧區。

請程式設計找出一條連線兩個不同牧場的路徑,使得連上這條路徑後,這個更大的新牧場有最小的直徑。

第1

11行: 乙個整數nnn(

1<=n

<

=150

)(1 <= n <= 150)

(1<=n

<=1

50), 表示牧區數

第2

22到n+1

n+1n+

1行: 每行兩個整數x,y

x,yx,y(0

<=x

,y<

=100000

)(0 <= x ,y<= 100000)

(0<=x

,y<=1

0000

0), 表示n

nn個牧區的座標。注意每個 牧區的座標都是不一樣的。

第n +2

n+2n+

2行到第2∗n

+12*n+1

2∗n+

1行: 每行包括n

nn個數字(0

00或1

11) 表示如上文描述的對稱鄰接矩陣。

只有一行,包括乙個實數,表示所求答案。數字保留六位小數。

input

810 10

15 10

20 10

15 15

20 15

30 15

25 10

30 10

01000000

10111000

01001000

01001000

01110000

00000010

00000101

00000010

output

22.071068板子

ac的floyed

#include

#include

#include

#include

using namespace std;

const double inf=0x7fffffff*1.0;

int n;

char c;

double d[220]

[220],b[220],r1=0,r2=2147483647,x[220],y[220]

;int main()}

for(int k=1;k<=n;k++)

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

if(i!=k&&j!=k&&i!=j&&d[i]

[j]>d[i]

[k]+d[k]

[j])

d[i]

[j]=d[i]

[k]+d[k]

[j]; //floyed演算法

for(int i=1;i<=n;i++)

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

if(i!=j&&d[i]

[j]==inf)

r2=min(r2,b[i]+b[j]+sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2))

); //連線兩點後最大的直徑

cout<

<

<

return 0;

}

80的dijkstra演算法

#include

#include

#include

#include

#include

using namespace std;

const double inf=0x7fffffff*1.0;

int n;

char c;

double d[220]

[220],dis[220]

[220],b[220],p[220],r1=0,r2=inf,x[220],y[220]

;int main()}

for(int k=1;k<=n;k++)

if(!w)break

; p[w]

=1;for

(int j=1;j<=n;j++)

if(p[j]

==0)

dis[k]

[j]=min(dis[k]

[j],dis[k]

[w]+d[w]

[j]);}

} //dijkstra演算法

for(int i=1;i<=n;i++)

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

if(i!=j&&d[i]

[j]==inf)

r2=min(r2,b[i]+b[j]+sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2))

); //判斷原來的大還是連線後的大

cout<

<

<

return 0;

}

牛的旅行 Floyed Warshall

原題鏈結傳送門 d es crip tion description descri ptio n農民john的農場裡有很多牧區。有的路徑連線一些特定的牧區。一片所有連通的牧區稱為乙個牧場。但是就目前而言,你能看到至少有兩個牧區不連通。這樣,農民john就有多個牧區了。john想在農場裡新增一條路徑 ...

1125 牛的旅行

農民john的農場裡有很多牧區,有的路徑連線一些特定的牧區。一片所有連通的牧區稱為乙個牧場。但是就目前而言,你能看到至少有兩個牧區不連通。現在,john想在農場裡新增一條路徑 注意,恰好一條 乙個牧場的直徑就是牧場中最遠的兩個牧區的距離 本題中所提到的所有距離指的都是最短的距離 考慮如下的兩個牧場,...

題解 洛谷P1552 牛的旅行(floyd)

這道題乍一看非常頭疼,但仔細讀完題之後,我們明白它其實想讓我們求兩個牧場間最小可能的直徑。對於直徑的定義就是牧場中最遠兩個牧區之間的距離,而這個距離指的是最短路的距離,那麼我們將直徑分開來求。先跑一邊floyd計算兩個點之間的最短路,然後記錄在同乙個牧場內假如以乙個點作為道路構建的乙個出發點,在該牧...