• POJ 2942


    POJ 2942

    题目大意:有n位骑士,他们间有一些仇恨关系,如果有仇恨则开会的时候不能坐在两侧,求至少删除多少名骑士,使得总可以找出奇数个骑士和平地坐下来开会?

    解:我挺天真的,一开始就去研究它给出的关系图,想了好久才去建补图。发现如果是可以坐在一起的话补图上就是一个圈,任务就是找奇圈,然后自己草莽地写了一个边双连通分量算,wa,调了略久,没思路,看题解,发现是点双连通(边双连通内可能有关节点,但是点双连通内一定没有桥,所以如果只是算出边双连通可能会因当中包含关节点而出错),况且我也是理解错题意了,我以为是找最大奇圈,但实际上是把所有的可能都算出来。正解首先是求点双连通,没找到一个块,对这个块进行染色。这里略略吐槽一下网上的说法,根本不是二分图么,只是用了验证二分图的更新方法。然后则是用了一个性质:如果块内有一个奇圈,那么这个块内的其他点也必定在某个奇圈上。(理解:如果块内的点位奇数,那么剩下的偶数点一定是在同一个奇圈(因为没有桥与关节点,一定可以组成回路),如果是偶数点,那么偶数-奇数=奇数,显然)注意题意1个点是不能算数的,但你也不同特殊计算,如果是染色找到一个奇圈后只有单个点剩下的话那么它一定是其他块内的点,作为一个关节点存在。

    View Code
      1 //poj 2942
    2 const
    3 maxn=1111;
    4 maxm=maxn*maxn;
    5 type
    6 data=record
    7 dest, next: longint;
    8 end;
    9 var
    10 edge: array[1..maxm]of data;
    11 g: array[1..maxn, 1..maxn]of boolean;
    12 bcc, col, cnt, vect, pre, low, dfn: array[1..maxn]of longint;
    13 stack: array[1..maxn, 0..1]of longint;
    14 visit: array[1..maxn]of boolean;
    15 key, ffff, color, ans, tot, n, m, time, stot: longint;
    16 procedure add(x, y: longint);
    17 begin
    18 inc(tot);
    19 with edge[tot] do begin
    20 dest := y;
    21 next := vect[x];
    22 vect[x] := tot;
    23 end;
    24 inc(tot);
    25 with edge[tot] do begin
    26 dest := x;
    27 next := vect[y];
    28 vect[y] := tot;
    29 end;
    30 end;
    31
    32 {procedure del(x, y: longint);
    33 var
    34 i, last: longint;
    35 begin
    36 if edge[vect[x]].dest = y then begin
    37 vect[x] := edge[vect[x]].next;
    38 end
    39 else begin
    40 i := vect[x];
    41 while i<>0 do
    42 with edge[i] do begin
    43 if dest = y then begin
    44 edge[last].next := next;
    45 break;
    46 end;
    47 last := i;
    48 i := next;
    49 end;
    50 end;
    51
    52 if edge[vect[y]].dest = x then begin
    53 vect[y] := edge[vect[y]].next;
    54 end
    55 else begin
    56 i := vect[y];
    57 while i<>0 do
    58 with edge[i] do begin
    59 if dest = x then begin
    60 edge[last].next := next;
    61 end;
    62 last := i;
    63 i := next;
    64 end;
    65 end;
    66 end; }
    67
    68 procedure init;
    69 var
    70 i, j, x, y: longint;
    71 begin
    72 tot := 0; ans := 0;
    73 fillchar(vect, sizeof(vect), 0);
    74 {for i := 1 to n-1 do
    75 for j := i + 1 to n do add(i, j);
    76 for i := 1 to m do begin
    77 readln(x, y);
    78 del(x, y);
    79 end; }
    80 fillchar(g, sizeof(g), true);
    81 for i := 1 to m do begin
    82 readln(x, y);
    83 g[x, y] := false; g[y, x] := false;
    84 end;
    85 for i := 1 to n-1 do
    86 for j := i+1 to n do
    87 if g[i, j] then add(i, j);
    88 end;
    89
    90 function check(x: longint): boolean;
    91 var
    92 i, tmp: longint;
    93 begin
    94 i := vect[x];
    95 tmp := (key << 1)+1 - col[x];
    96 while i<>0 do
    97 with edge[i] do begin
    98 if pre[x]<>dest then
    99 if bcc[dest]=color then begin
    100 if (col[dest]<key) then begin
    101 col[dest] := tmp;
    102 if check(dest) then exit(true);
    103 end
    104 else if col[dest]<>tmp then exit(true);
    105 end;
    106 i := next;
    107 end;
    108 check := false;
    109 end;
    110
    111 procedure calc_bcc(x, y: longint);
    112 var
    113 i, tmp: longint;
    114 begin
    115 tmp := stot;
    116 inc(stot); inc(color);
    117 repeat
    118 dec(stot);
    119 bcc[stack[stot][0]] := color; bcc[stack[stot][1]] := color;
    120 until ((stack[stot][0]=x)and(stack[stot][1]=y)or(stot=0));
    121 if stot>0 then dec(stot);
    122 //fillchar(col, sizeof(col), 0);
    123 inc(key, 2);
    124 col[x] := key;
    125 if (check(x)) then begin
    126 for i := stot +1 to tmp do begin
    127 cnt[stack[i][0]] := 1; cnt[stack[i][1]] := 1;
    128 end;
    129 end;
    130 end;
    131
    132 procedure tarjan(x: longint);
    133 var
    134 i: longint;
    135 begin
    136 visit[x] := true;
    137 inc(time);
    138 dfn[x] := time; low[x] := time;
    139 i := vect[x];
    140 while i<>0 do
    141 with edge[i] do begin
    142 if dest<>pre[x] then begin
    143 if dfn[dest]=0 then begin
    144 inc(stot);
    145 stack[stot][0] := x;
    146 stack[stot][1] := dest;
    147 pre[dest] := x;
    148 tarjan(dest);
    149 if low[dest]<low[x] then low[x] := low[dest];
    150 if (dfn[x]<=low[dest])or(x=ffff) then begin
    151 calc_bcc(x, dest);
    152 end;
    153 end
    154 else if visit[dest] then begin
    155 if dfn[dest]<low[x] then low[x] := dfn[dest];
    156 end;
    157 end;
    158 i := next;
    159 end;
    160 visit[x] := false;
    161 end;
    162
    163 procedure main;
    164 var
    165 i, u: longint;
    166 begin
    167 fillchar(dfn, sizeof(dfn), 0);
    168 fillchar(pre, sizeof(pre), 0);
    169 fillchar(cnt, sizeof(cnt), 0);
    170
    171 fillchar(col, sizeof(col), 0);
    172
    173 fillchar(visit, sizeof(visit), 0);
    174 fillchar(bcc, sizeof(bcc), 0);
    175 time := 0; stot := 0; color := 0; key := 0;
    176 for i := 1 to n do if dfn[i]=0 then begin
    177 ffff := i; tarjan(i);
    178 end;
    179 for i := 1 to n do
    180 if (cnt[i]=0) then inc(ans);
    181 end;
    182
    183 procedure print;
    184 begin
    185 writeln(ans);
    186 end;
    187
    188 begin
    189 assign(input,'1.txt'); reset(input);
    190 readln(n, m);
    191 while (n+m<>0) do begin
    192 init;
    193 main;
    194 print;
    195 readln(n, m);
    196 end;
    197 end.



  • 相关阅读:
    JQuery:JQuery语法、选择器、事件处理
    循序渐进DB2(第2版)——DBA系统管理、运维与应用案例
    高级进阶DB2(第2版)——内部结构、高级管理与问题诊断
    DB2数据库性能调整和优化(第2版)
    金融工程中的蒙特卡罗方法
    代数学教程
    拓扑线性空间与算子谱理论
    李代数(第2版)
    编程的修炼(中英双语)
    iOS应用开发详解
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435208.html
Copyright © 2020-2023  润新知