zoukankan      html  css  js  c++  java
  • poj2594

    特殊的最小路径覆盖
    回顾一下经典的最小路径覆盖问题是每个点都恰好被一条路径覆盖
    我们把有向无环图的点拆成i,i',对于原图中边i--->j,连边i-->j'
    做最大匹配,答案是原图点数-最大匹配
    但这道题每个点可以被覆盖多次,所以我们考虑先dfs出每个点可以访问的点
    然后拆点,如果i可以到达j,那么连边i-->j',答案是原图点数-最大匹配
    为什么呢,感性的想一下,在最小路径覆盖的基础上既然每个点可以被多次经过
    那么干脆我们把两个可达的点认为是直接飞过去就好了~ ~

     1 type node=record
     2        point,next:longint;
     3      end;
     4 
     5 var edge:array[0..200010] of node;
     6     a:array[0..510,0..510] of boolean;
     7     p,cx,cy:array[0..510] of longint;
     8     v:array[0..510] of boolean;
     9     x,y,n,m,i,j,ans,len:longint;
    10 
    11 procedure add(x,y:longint);
    12   begin
    13     inc(len);
    14     edge[len].point:=y;
    15     edge[len].next:=p[x];
    16     p[x]:=len;
    17   end;
    18 
    19 function find(x:longint):longint;
    20   var i,y:longint;
    21   begin
    22     i:=p[x];
    23     while i<>-1 do
    24     begin
    25       y:=edge[i].point;
    26       if not v[y] then
    27       begin
    28         v[y]:=true;
    29         if (cy[y]=-1) or (find(cy[y])=1) then
    30         begin
    31           cx[x]:=y;
    32           cy[y]:=x;
    33           exit(1);
    34         end;
    35       end;
    36       i:=edge[i].next;
    37     end;
    38     exit(0);
    39   end;
    40 
    41 procedure dfs(x:longint);
    42   var i,y:longint;
    43   begin
    44     i:=p[x];
    45     v[x]:=true;
    46     while i<>-1 do
    47     begin
    48       y:=edge[i].point;
    49       if not v[y] then dfs(y);
    50       i:=edge[i].next;
    51     end;
    52   end;
    53 
    54 begin
    55   readln(n,m);
    56   while (n<>0) do
    57   begin
    58     ans:=0;
    59     len:=0;
    60     fillchar(p,sizeof(p),255);
    61     fillchar(a,sizeof(a),false);
    62     for i:=1 to m do
    63     begin
    64       readln(x,y);
    65       add(x,y);
    66       a[x,y]:=true;
    67     end;
    68     for i:=1 to n do
    69     begin
    70       fillchar(v,sizeof(v),false);
    71       dfs(i);
    72       for j:=1 to n do
    73         if v[j] and (i<>j) and not a[i,j] then
    74           add(i,j);
    75     end;
    76     fillchar(cx,sizeof(cx),255);
    77     fillchar(cy,sizeof(cy),255);
    78     for i:=1 to n do
    79       if cx[i]=-1 then
    80       begin
    81         fillchar(v,sizeof(v),false);
    82         ans:=ans+find(i);
    83       end;
    84     writeln(n-ans);
    85     readln(n,m);
    86   end;
    87 end.
    View Code
  • 相关阅读:
    Codeforces Round #518 Div. 1没翻车记
    BZOJ4310 跳蚤(后缀数组+二分答案)
    后缀数组备忘
    洛谷 P3573 [POI2014]RAJ-Rally 解题报告
    洛谷 P1503 鬼子进村 解题报告
    洛谷 P2375 [NOI2014]动物园 解题报告
    洛谷 P2797 Facer的魔法 解题报告
    【模板】三分法
    那些神奇的DP建模
    洛谷 P1136 迎接仪式 解题报告
  • 原文地址:https://www.cnblogs.com/phile/p/4473080.html
Copyright © 2011-2022 走看看