码迷,mamicode.com
首页 > 其他好文 > 详细

poj3041 Asteroids(二分图最小顶点覆盖、二分图匹配)

时间:2017-03-11 18:54:13      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:proc   points   exp   nts   eset   ram   next   with   any   

Description

Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently located at the lattice points of the grid. 

Fortunately, Bessie has a powerful weapon that can vaporize all the asteroids in any given row or column of the grid with a single shot.This weapon is quite expensive, so she wishes to use it sparingly.Given the location of all the asteroids in the field, find the minimum number of shots Bessie needs to fire to eliminate all of the asteroids.

Input

* Line 1: Two integers N and K, separated by a single space. 
* Lines 2..K+1: Each line contains two space-separated integers R and C (1 <= R, C <= N) denoting the row and column coordinates of an asteroid, respectively.

Output

* Line 1: The integer representing the minimum number of times Bessie must shoot.

Sample Input

3 4
1 1
1 3
2 2
3 2

Sample Output

2

Hint

INPUT DETAILS: 
The following diagram represents the data, where "X" is an asteroid and "." is empty space: 
X.X 
.X. 
.X.
 


OUTPUT DETAILS: 
Bessie may fire across row 1 to destroy the asteroids at (1,1) and (1,3), and then she may fire down column 2 to destroy the asteroids at (2,2) and (3,2).

Source

USACO 2005 November Gold
 
 
分别以n个行和n个列为结点,建立二分图,每一个星球对应一个连接其所在行和列的边,问题转化为求这个二分图的最小顶点覆盖。
在二分图中,有结论:最小顶点覆盖数=最大匹配数
自己yy了一个证明:
首先,我们证明不存在小于最大匹配数的最小顶点覆盖数。
这是显然的,因为这些顶点根本无法覆盖所有的匹配边。
接下来证明存在等于最大匹配数的最小顶点覆盖数。
首先证明,在最大匹配中,每条匹配边连接的两个顶点a,b最多只有一个与非匹配点有连边。
用反证法:假设a与c,b与d这件都有边,且c,d都不是匹配点,则可以去掉连接a,b的匹配边,加上连接a,c和连接b,d的匹配边,是匹配数+1,这与最大匹配矛盾。
这样,我们构造这样一个顶点集合:对于每条匹配边,选择其连接的两个点中的一个(如果两个点有与非匹配点有连边的点,则选那个点;否则随便选一个)。
这个集合中有最大匹配数个点。
我们证明:这个点集能覆盖所有的边。
若一条边是匹配边,则其显然被覆盖。
若一条边不是匹配边:
1)若其与某匹配顶点有连边,则该匹配顶点必在我们构造的点集中,所以该边被覆盖
2)若其连接着两个非匹配点,则可以增加这条边为匹配边,是匹配数+1,这与最大匹配矛盾,故此情况不成立
所以,这个点集能覆盖所有的边。
综上所述,在二分图中,最小顶点覆盖数=最大匹配数已得到证明。
 1 program rrr(input,output);
 2 const
 3   inf=123456789;
 4 type
 5   etype=record
 6      t,c,rev,next:longint;
 7   end;
 8 var
 9   e:array[0..20020]of etype;
10   a,cur,d:array[-505..505]of longint;
11   q:array[0..1010]of longint;
12   n,m,i,x,y,h,t,cnt,ans:longint;
13 procedure ins(x,y,c:longint);
14 begin
15    inc(cnt);e[cnt].t:=y;e[cnt].c:=c;e[cnt].next:=a[x];a[x]:=cnt;
16 end;
17 procedure add(x,y:longint);
18 begin
19    ins(x,y,1);ins(y,x,0);
20    e[cnt].rev:=cnt-1;e[cnt-1].rev:=cnt;
21 end;
22 function min(a,b:longint):longint;
23 begin
24    if a<b then exit(a) else exit(b);
25 end;
26 procedure bfs;
27 begin
28    for i:=-n to n+1 do d[i]:=-1;
29    h:=0;t:=1;q[1]:=0;d[0]:=0;
30    while h<t do
31       begin
32          inc(h);
33          i:=a[q[h]];
34          while i<>inf do
35             begin
36                if (d[e[i].t]=-1) and (e[i].c>0) then
37                   begin
38                      d[e[i].t]:=d[q[h]]+1;
39                      inc(t);q[t]:=e[i].t;
40                   end;
41                i:=e[i].next;
42             end;
43       end;
44 end;
45 function dfs(k,f:longint):longint;
46 var
47   ans,r,i:longint;
48 begin
49    if (k=n+1) or (f=0) then exit(f);
50    ans:=0;i:=cur[k];
51    while i<>inf do
52       begin
53          if (e[i].c>0) and (d[e[i].t]=d[k]+1) then
54             begin
55                r:=dfs(e[i].t,min(f,e[i].c));
56                dec(e[i].c,r);inc(e[e[i].rev].c,r);
57                ans:=ans+r;f:=f-r;
58                if f=0 then break;
59             end;
60          i:=e[i].next;
61          cur[k]:=i;
62       end;
63    if f>0 then d[k]:=-1;
64    exit(ans);
65 end;
66 begin
67    assign(input,r.in);assign(output,r.out);reset(input);rewrite(output);
68    readln(n,m);
69    cnt:=0;for i:=-n to n+1 do a[i]:=inf;
70    for i:=1 to n do begin add(0,-i);add(i,n+1); end;
71    for i:=1 to m do begin readln(x,y);add(-x,y); end;
72    ans:=0;
73    while true do
74       begin
75          bfs;
76          if d[n+1]=-1 then break;
77          for i:=-n to n+1 do cur[i]:=a[i];
78          ans:=ans+dfs(0,inf);
79       end;
80    write(ans);
81    close(input);close(output);
82 end.

 

poj3041 Asteroids(二分图最小顶点覆盖、二分图匹配)

标签:proc   points   exp   nts   eset   ram   next   with   any   

原文地址:http://www.cnblogs.com/Currier/p/6535734.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!