poj 2749

解决 Farmer John 的农场中牛棚连接问题,通过构建图论模型并使用 Kosaraju 算法寻找最优路径布局,确保所有牛棚通过两个中转站有效连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

FarmerJohn's farm has N barns, and there are some cows that live in each barn. Thecows like to drop around, so John wants to build some roads to connect thesebarns. If he builds roads for every pair of different barns, then he must buildN * (N - 1) / 2 roads, which is so costly that cheapskate John will never dothat, though that's the best choice for the cows. 

Clever John just had another good idea. He first builds two transferring pointS1 and S2, and then builds a road connecting S1 and S2 and N roads connectingeach barn with S1 or S2, namely every barn will connect with S1 or S2, but notboth. So that every pair of barns will be connected by the roads. To make thecows don't spend too much time while dropping around, John wants to minimizethe maximum of distances between every pair of barns. 

That's not the whole story because there is another troublesome problem. Thecows of some barns hate each other, and John can't connect their barns to thesame transferring point. The cows of some barns are friends with each other,and John must connect their barns to the same transferring point. What aheadache! Now John turns to you for help. Your task is to find a feasibleoptimal road-building scheme to make the maximum of distances between everypair of barns as short as possible, which means that you must decide whichtransferring point each barn should connect to. 

We have known the coordinates of S1, S2 and the N barns, the pairs of barns inwhich the cows hate each other, and the pairs of barns in which the cows arefriends with each other. 

Note that John always builds roads vertically and horizontally, so the lengthof road between two places is their Manhattandistance. For example, saying two points with coordinates (x1, y1) and (x2,y2), the Manhattandistance between them is |x1 - x2| + |y1 - y2|. 

Input

The firstline of input consists of 3 integers N, A and B (2 <= N <= 500, 0 <= A<= 1000, 0 <= B <= 1000), which are the number of barns, the number ofpairs of barns in which the cows hate each other and the number of pairs ofbarns in which the cows are friends with each other. 

Next line contains 4 integer sx1, sy1, sx2, sy2, which are the coordinates oftwo different transferring point S1 and S2 respectively. 

Each of the following N line contains two integer x and y. They are coordinatesof the barns from the first barn to the last one. 

Each of the following A lines contains two different integers i and j(1 <= i< j <= N), which represent the i-th and j-th barns in which the cows hateeach other. 

The same pair of barns never appears more than once. 

Each of the following B lines contains two different integers i and j(1 <= i< j <= N), which represent the i-th and j-th barns in which the cows arefriends with each other. The same pair of barns never appears more than once. 

You should note that all the coordinates are in the range [-1000000, 1000000]. 

Output

You justneed output a line containing a single integer, which represents the maximum ofthe distances between every pair of barns, if John selects the optimalroad-building scheme. Note if there is no feasible solution, just output -1.

Sample Input

4 1 1

12750 28546 15361 32055

6706 3887

10754 8166

12668 19380

15788 16059

3 4

2 3

Sample Output

53246

 

题意:有n个牛棚, 还有两个中转站S1和S2, S1和S2用一条路连接起来。 为了使得任意牛棚两个都可以有道路联通,现在要让每个牛棚都连接一条路到S1或者S2。

有a对牛棚互相有仇恨,所以不能让他们的路连接到同一个中转站。还有b对牛棚互相喜欢,所以他们的路必须连到同一个中专站。

道路的长度是两点的曼哈顿距离.红色就是曼哈顿距离。



分析:

一、若两点的某种选择的连接方式使得这两点间的距离大于最大距离则矛盾,然后加边。

二、根据仇恨情况和喜欢情况加边。

二分找答案。

type

 node=record

 x,y,next:longint;

end;

 

var

 e,n,a1,b1,x1,x2,y1,y2,tot,f1:longint;

 x,y:array[1..500] of longint;

 a,b:array[1..1000,1..2] of longint;

 g:array[1..1000000] of node;

 belong,ls,f:array[1..2000] of longint;

 v:array[1..2000] of boolean;

 

procedure add(x,y:longint);

begin

 inc(e);

 g[e].x:=x;

 g[e].y:=y;

 g[e].next:=ls[x];

 ls[x]:=e;

end;

 

procedure init;

var

 i:longint;

begin

 readln(n,a1,b1);

 readln(x1,y1,x2,y2);

 for i:=1 to n do

   readln(x[i],y[i]);

 for i:=1 to a1 do

   readln(a[i,1],a[i,2]);

 for i:=1 to b1 do

   readln(b[i,1],b[i,2]);

end;

 

procedure build(mid:longint);

var

 s,i,j:longint;

begin

 e:=0;

 fillchar(ls,sizeof(ls),0);

 for i:=1 to a1 do

 begin

   add(a[i,1],a[i,2]+n);

   add(a[i,1]+n,a[i,2]);

   add(a[i,2],a[i,1]+n);

   add(a[i,2]+n,a[i,1]);

 end;

 for i:=1 to b1 do

 begin

   add(b[i,1],b[i,2]);

   add(b[i,1]+n,b[i,2]+n);

   add(b[i,2],b[i,1]);

   add(b[i,2]+n,b[i,1]+n);

 end;

 s:=abs(x1-x2)+abs(y1-y2);

 for i:=1 to n-1 do

   for j:=i+1 to n do

   begin

     if abs(x[i]-x1)+abs(y[i]-y1)+abs(x[j]-x1)+abs(y[j]-y1)>mid then

     begin

       add(i,j+n);

       add(j,i+n);

     end;

     if abs(x[i]-x2)+abs(y[i]-y2)+abs(x[j]-x2)+abs(y[j]-y2)>mid then

      begin

       add(i+n,j);

       add(j+n,i);

     end;

     if abs(x[i]-x1)+abs(y[i]-y1)+abs(x[j]-x2)+abs(y[j]-y2)+s>mid then

     begin

       add(i,j);

       add(j+n,i+n);

     end;

     if abs(x[i]-x2)+abs(y[i]-y2)+abs(x[j]-x1)+abs(y[j]-y1)+s>mid then

     begin

       add(i+n,j+n);

       add(j,i);

     end;

   end;

end;

 

procedure dfs(x:longint);

var

 i:longint;

begin

 v[x]:=false;

 i:=ls[x];

 while i>0 do

   with g[i] do

   begin

     if v[y] then dfs(y);

     i:=next;

   end;

 if tot=0

   then begin

          inc(f1);

          f[f1]:=x;

        end

   else belong[x]:=tot;

end;

 

procedure kosaraju;

var

 i:longint;

begin

 tot:=0;

 f1:=0;

 fillchar(v,sizeof(v),true);

 for i:=1 to n*2 do

   if v[i] then dfs(i);

 fillchar(ls,sizeof(ls),0);

 for i:=1 to e do

   add(g[i].y,g[i].x);

 fillchar(v,sizeof(v),true);

 for i:=n*2 downto 1 do

   if v[f[i]] then

   begin

     inc(tot);

     dfs(f[i]);

   end;

end;

 

procedure main;

var

 l,r,mid,ans,i:longint;

 flag:boolean;

begin

 l:=0;

 r:=4000000;

 ans:=maxlongint;

 while l<=r do

 begin

   mid:=(l+r) div 2;

   build(mid);

   kosaraju;

   flag:=true;

   for i:=1 to n do

     if belong[i]=belong[i+n] then

     begin

       flag:=false;

       break;

     end;

   if flag

     then begin

             if mid<ans then ans:=mid;

             r:=mid-1;

          end

     else l:=mid+1;

 end;

 if ans=maxlongint then ans:=-1;

 writeln(ans);

end;

 

begin

 init;

 main;

end.

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值