• POJ 1904


    POJ 1904

    题目大意:有n个王子和n个美人,每个王子喜欢一些美人,如果一个王子要娶一个美人,必须是他喜欢的。现在国王的巫师给出了一个完美匹配表(每个王子都能娶到他喜欢的女孩),现在国外想知道在不影响全部王子能娶到老婆的前提下,每个王子能有哪些选择?

    解:重复许多人的话:这是一条好题。一开始我自己觉得意识模糊,于是不断删去唯一的匹配边(只有一个王子喜欢的女孩和只喜欢一个女孩的王子),然后默认其他的都可以替换。其实也意识到了是一个增广路的模型,只是没有去细想,想当然会tle的。

    正解则是在增广路的基础上,因为给出了一个完美匹配。所以设目前王子为xi, 他初始匹配的美人为yi,如果王子选择了其他美人, 则有一条增广路出去,但奇妙的事情发生了, 如果这个增广路可行的话, 则一定有一位王子会娶掉yi,如果连一条yi到xi的边,这条路径就成了一个环!!这路径包含的点成为了一个强连通分量,所以我们用连边建图,tarjan后处理顺序输出即可。

    View Code
      1 const
    2 maxm=211111 << 1;
    3 maxn=2111;
    4 type
    5 data=record
    6 dest, next, op: longint;
    7 end;
    8 var
    9 edge: array[1..maxm]of data;
    10 ans, s, dfn, low, vect, col: array[1..maxn*2]of longint;
    11 visit: array[1..maxn*2]of boolean;
    12 time, stot, color, tot, n: longint;
    13 procedure add(x, y: longint);
    14 begin
    15 inc(tot);
    16 with edge[tot] do begin
    17 dest := y;
    18 next := vect[x];
    19 vect[x] := tot;
    20 end;
    21 end;
    22
    23 procedure init;
    24 var
    25 i, j, x, y: longint;
    26 begin
    27 tot := 0;
    28 fillchar(vect, sizeof(vect), 0);
    29 readln(n);
    30 for i := 1 to n do begin
    31 read(x);
    32 for j := 1 to x do begin
    33 read(y);
    34 add(i, y+n);
    35 end;
    36 readln;
    37 end;
    38 for i := 1 to n do begin
    39 read(x);
    40 add(x+n, i);
    41 end;
    42 readln;
    43 end;
    44
    45 procedure tarjan(x: longint);
    46 var
    47 i, u: longint;
    48 begin
    49 inc(time);
    50 dfn[x] := time; low[x] := time;
    51 inc(stot);
    52 s[stot] := x; visit[x] := true;
    53 i := vect[x];
    54 while i<>0 do
    55 with edge[i] do begin
    56 if dfn[dest]=0 then begin
    57 tarjan(dest);
    58 if low[dest]<low[x] then low[x] := low[dest];
    59 end
    60 else if visit[dest] then begin
    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 procedure main;
    77 var
    78 i: longint;
    79 begin
    80 fillchar(col, sizeof(col), 0);
    81 fillchar(visit, sizeof(visit), 0);
    82 color := 0; time := 0;
    83 for i := 1 to n do
    84 if dfn[i]=0 then tarjan(i);
    85 end;
    86
    87 procedure sort(b, e: longint);
    88 var
    89 i, j, k: longint;
    90 begin
    91 for i := 1 to e - 1 do
    92 for j := i+1 to e do
    93 if ans[i]>ans[j] then begin
    94 k := ans[i];
    95 ans[i] := ans[j];
    96 ans[j] := k;
    97 end;
    98 end;
    99
    100 procedure print;
    101 var
    102 i, j, tmp: longint;
    103 begin
    104 for j := 1 to n do begin
    105 tmp := 0;
    106 i := vect[j];
    107 while i<>0 do
    108 with edge[i] do begin
    109 if col[dest]=col[j] then begin
    110 inc(tmp);
    111 ans[tmp] := dest-n;
    112 end;
    113 i := next;
    114 end;
    115 sort(1, tmp);
    116 write(tmp);
    117 for i := 1 to tmp do write(' ', ans[i]);
    118 writeln;
    119 end;
    120 end;
    121
    122 begin
    123 assign(input,'1.txt'); reset(input);
    124 init;
    125 main;
    126 print;
    127 end.



  • 相关阅读:
    [CSP-S模拟测试]:甜圈(线段树)
    BZOJ4539 [Hnoi2016]树 【倍增 + 主席树】
    Myhchael原创题系列 Mychael vs Kid 【题解】
    BZOJ2668 [cqoi2012]交换棋子 【费用流】
    BZOJ1596 [Usaco2008 Jan]电话网络 【树形dp】
    BZOJ3427 Poi2013 Bytecomputer 【dp】
    BZOJ3526 [Poi2014]Card 【线段树】
    BZOJ3542 DZY Loves March 【map + 线段树】
    BZOJ3832 [Poi2014]Rally 【拓扑序 + 堆】
    HDU 1083
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435181.html
Copyright © 2020-2023  润新知