| ||||||||||
Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:理解了。。有图有真相In Reply To:还望指点一二。 Posted by:yayu_myself at 2010-01-06 20:59:16 理解了。。以sample为例,把行的点看做left集,列的点看做right集,我们可以画出如下图: 空格用*代替了。。怕没法填充。。 1————————1 *\ **\ 2—-\——2 ****\/ ****/\ ***/**\ **/****\ */******\ 3********3 太佩服我了- -。。 其中每条边都代表一个障碍。。那么目的是要用最少的点消灭障碍,即图中的边,就是 最小覆盖: 最小覆盖要求用最少的点(左右两边的点)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数,最大匹配用匈牙利算法,匈牙利不懂见这里: http://imlazy.ycool.com/post.1603708.html 我的AC如下: #include <stdio.h> #include <string.h> #define N 501 char map[N][N], used[N]; int match[N]; int find(int k, int n) { int i; for (i = 1; i <= n; i++) if (map[k][i] && !used[i]) { used[i] = 1; if (match[i] == -1 || find(match[i], n)) { match[i] = k; return 1; } } return 0; } int hungary(int n) { int i, res; memset(match, -1, sizeof(match)); res = 0; for (i = 1; i <= n; i++) { memset(used, 0, sizeof(used)); if (find(i, n)) res++; } return res; } int main(void) { int n, k, i, r, c, res; scanf("%d%d", &n, &k); for (i = 0; i < k; i++) { scanf("%d%d", &r, &c); map[r][c] = 1; } printf("%d", hungary(n)); return 0; } Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator