zoukankan      html  css  js  c++  java
  • POJ 2749

    POJ 2749

    题目大意:给出若干个牛棚的坐标,现有两个点d1, d2(交通枢纽点),d1, d2之间有一条路(本题两点的路程为横坐标之差和纵坐标之差的绝对值),求牛棚连到d1,或d2,任意两个牛棚之间最大值的最小值是多少。他还加了一个约束条件,就是给出a对牛棚,每对牛棚是不能连在同一个枢纽点,再给出b对牛棚,每对牛棚一定要连在同一个枢纽点。

    解:上网找做法,说这个是一种2sat模型,属于np模型、主要是讨论有节点关系为一定共存和一定不共存这样一些的图。这道题目也是一样(要么不能一起,要么一起),核心思想是二分答案(和noip2010 no3类似,有时间复习),然后建图讨论是否可行。设x为x处于d1,x+n为x处于d2,然后讨论他们。(建图:定义,如果有a->b说明选择了a则一定要选则b)如果dist[i][1]+dist[j][1]>mid,说明如果点i和点j都连在d1则一定超过,所以对与i连d1时,j一定只能连d2,所以连上一条i->j+n的边,而如果j连d1,那么i必须连d2,所以连边j->i+n,然后根据构图的对称性(这个要看论文仔细钻研)可知选择了一个点,他和他连向的点一定是一个强联通分量,所以tarjan一次,然后找出如果存在col[i]=col[i+n]则说明这幅图不能成立(显然,连d1的同时练d2才成立,显然违反题意了)

    注释:好二,因为边的数量又算少了,wa了好多次+浪费了一个多小时。虽然不在乎ac率了,可无谓的错误还是不应该的。

    View Code
      1 const
    2 maxn=522 *2;
    3 bilibili=maxlongint >> 1;
    4 inf=55555555;
    5 type
    6 data=record
    7 dest, next: longint;
    8 end;
    9 dota=record
    10 a, b: longint;
    11 end;
    12 var
    13 edge: array[1..maxn * maxn]of data;
    14 dfn, low, s, vect, col:array[1..maxn]of longint;
    15 hate, friend: array[1..maxn]of dota;
    16 dist: array[1..maxn, 1..2]of longint;
    17 visit: array[1..maxn]of boolean;
    18 sx1, sx2, sy1, sy2, time, d, color, stot, tot, n, a, b, ans: longint;
    19 procedure add(x, y: longint);
    20 begin
    21 inc(tot);
    22 with edge[tot] do begin
    23 dest := y;
    24 next := vect[x];
    25 vect[x] := tot;
    26 end;
    27 end;
    28
    29 procedure init;
    30 var
    31 i, j, x, y: longint;
    32 begin
    33 readln(n, a, b);
    34 readln(sx1, sy1, sx2, sy2);
    35 d := abs(sx1-sx2)+abs(sy1-sy2);
    36 for i := 1 to n do begin
    37 readln(x, y);
    38 dist[i][1] := abs(sx1-x) + abs(sy1-y);
    39 dist[i][2] := abs(sx2-x) + abs(sy2-y);
    40 end;
    41 for i := 1 to a do readln(hate[i].a, hate[i].b);
    42 for i := 1 to b do readln(friend[i].a, friend[i].b);
    43 end;
    44
    45 procedure tarjan(x: longint);
    46 var
    47 i, u: longint;
    48 begin
    49 inc(time); inc(stot);
    50 dfn[x] := time; low[x] := dfn[x];
    51 s[stot] := x; visit[x] := true;
    52 i := vect[x];
    53 while i<>0 do
    54 with edge[i] do begin
    55 if dfn[dest]=0 then begin
    56 tarjan(dest);
    57 if low[dest]<low[x] then low[x] := low[dest];
    58 end
    59 else begin
    60 if visit[dest] then
    61 if dfn[dest]<low[x] then low[x] := dfn[dest];
    62 end;
    63 i := next;
    64 end;
    65 if dfn[x]=low[x] then begin
    66 inc(color);
    67 repeat
    68 u := s[stot];
    69 visit[u] := false;
    70 dec(stot);
    71 col[u] := color;
    72 until u=x;
    73 end;
    74 end;
    75
    76 function check(key: longint): boolean;
    77 var
    78 i, j, x, y: longint;
    79 begin
    80 tot := 0;
    81 fillchar(vect, sizeof(vect), 0);
    82 for i := 1 to n - 1 do
    83 for j := i+1 to n do begin
    84 if dist[i][1]+dist[j][1]>key then begin add(i, j+n); add(j, i+n); end;
    85 if dist[i][2]+dist[j][2]>key then begin add(i+n, j); add(j+n, i); end;
    86 if dist[i][1]+dist[j][2]+d>key then begin add(i, j); add(j+n, i+n); end;
    87 if dist[i][2]+dist[j][1]+d>key then begin add(i+n, j+n); add(j, i); end;
    88 end;
    89 for i := 1 to a do begin
    90 x := hate[i].a; y := hate[i].b;
    91 add(x, y+n); add(x+n, y); add(y, x+n); add(y+n, x);
    92 end;
    93 for i := 1 to b do begin
    94 x := friend[i].a; y := friend[i].b;
    95 add(x, y); add(x+n, y+n); add(y, x); add(y+n, x+n);
    96 end;
    97
    98 color := 0; stot := 0; time := 0;
    99 fillchar(col, sizeof(col), 0);
    100 fillchar(dfn, sizeof(dfn), 0);
    101 fillchar(visit, sizeof(visit), 0);
    102 for i := 1 to n*2 do
    103 if col[i]=0 then tarjan(i);
    104
    105 for i := 1 to n do
    106 if col[i]=col[i+n] then exit(false);
    107 exit(true);
    108 end;
    109
    110 procedure main;
    111 var
    112 st, ed, mid: longint;
    113 begin
    114 st := 0; ed := inf; ans := -1;
    115 while st<=ed do begin
    116 mid := (st+ed) >> 1;
    117 if check(mid) then begin
    118 ed := mid -1;
    119 ans := mid;
    120 end
    121 else st := mid + 1;
    122 end;
    123 end;
    124
    125 procedure print;
    126 begin
    127 writeln(ans);
    128 end;
    129
    130 begin
    131 assign(input,'1.txt'); reset(input);
    132 while not(seekeof) do begin
    133 init;
    134 main;
    135 print;
    136 end;
    137 end.



  • 相关阅读:
    新闻发布项目——实体类(comment)
    新闻发布项目——实体类(comment)
    新闻发布项目——实体类(newsTb)
    新闻发布项目——实体类(newsTb)
    新闻发布项目——实体类(newsTb)
    新闻发布项目——实体类(User)
    新闻发布项目——实体类(User)
    新闻发布项目——实体类(User)
    2016经典微小说:《轮回》
    要么干,要么滚,千万别混
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435184.html
Copyright © 2011-2022 走看看