您的位置:首页 > 其它

poj 2749

2016-06-13 19:41 197 查看
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.

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: