uva 11419最小点覆盖和…
来源:互联网 发布:淘宝运送方式怎么设置 编辑:程序博客网 时间:2024/06/06 20:34
大概题意:在一个R*C大小的网格中,网格上面放着一些目标,可以在网格外面发射子弹,子弹可以沿着垂直或则水平的方向射出,并打掉该路径上的所有目标,问最少需要多少子弹,并把这些子弹的位置输出。
我们先来确定非匹配边的情况,对于一条非匹配边,我们可以确定这条边肯定有一个点或两个点都属于匹配点 , 对于只有一个点属于匹配点 ,那么我们肯定要选这个匹配点 , 因此 , 我们只需要在求出最大匹配之后 , 再用X集合中的非匹配点去发展匈牙利树 ,然后我们标记X集合和Y集合中已经走过的点 , 最后 X 中没有标记的点和 Y 中已经标记的点 , 就是子弹的位置 。由于我们是用非匹配点去发展匈牙利树 , 因此如果存在边 , 那么我们就一定要选这条边的另外一个点 , 并且这个点一定是匹配点 ,那么和这个点相连的所有边就已经都覆盖了 , 再往后面的匈牙利树 , 我们就能很容易得出了。
对于匹配边 , 在我们后面已经得到的匈牙利树中 ,如果匹配边已经在这个树种 , 那么我们可以确定这条边肯定已经被覆盖 , 对于不在匈牙利树中的匹配边 ,我们可以确定这条匹配边上的X集合中的点 , 肯定没有被标记 , 那么根据上面的输出规则 , 我们可以确定用这中方法得到的点 ,肯定已经覆盖了所有边。
解法:每发射一个子弹,我们就能把某一行或者某一列的目标都清楚掉,因此我们每一行、每一列看成一个目标,并把这一行、列中的目标都标同一个号,那么我们就能通过同一个位置的目标来得到这个位置所在行、列的关系(在它们之间连一条边),我们要求的就转化为,用最少的点去覆盖所有的边,也就是最小点覆盖 , 也就是这个二分图的最大匹配。
子弹的位置:首先我们要知道 , 对于二分匹配算法 , 一定会遍历所有边 , 也就是说所有边都会属于一个或多个匈牙利树 。我们先把这些边分为匹配边和非匹配边 。
代码:
#define MAXN 1010#define INF 1000000#define max(x , y) (x)>(y)?(x):(y)#define min(x , y) (x)<(y)?(x):(y)int n , m , k; // 记录每条边的权值int pre[MAXN] ; // 记录和y中点匹配的点是哪个点vectorgrap[MAXN];int wr[MAXN] , wc[MAXN];int cx[MAXN] , cy[MAXN];int bzx[MAXN] , bzy[MAXN];void init(){memset(wr , 0 , sizeof(wr));memset(wc , 0 , sizeof(wc)); for(int i = 1; i<= n; i++) { grap[i].clear(); } memset(cx , -1 ,sizeof(cx)); memset(cy , -1 ,sizeof(cy));}bool match(int i) // 寻找增广路{ bzx[i] = 1; for(int j = 0; j< grap[i].size(); j++) { int v = grap[i][j]; if(!pre[v]) { pre[v] =1;bzy[v] = 1; if(cy[v]== -1 || match(cy[v])) { cx[i] = v; cy[v] = i; return true; } } } return false;}int km(){ int i ; memset(bzx , 0 ,sizeof(bzx));memset(bzy , 0 , sizeof(bzy)); int res = 0; for(i = 1; i<= n; i++) { if(cx[i] == -1&& wr[i]) { memset(pre, 0 , sizeof(pre)); if(match(i)) res += 1; } } return res;}int main(){ while(scanf("%d %d %d" ,&n , &m , &k) !=EOF) { if(n+m+k == 0) break; init(); int i , x , y ; for(i = 1; i <= k; i++){scanf("%d %d" , &x ,&y);grap[x].push_back(y);wr[x] = wc[y] = 1;} x = km();km(); printf("%d" , x);for(i = 1; i <= n; i++)if(!bzx[i] && wr[i]) printf(" r%d" , i);for(i = 1; i <= m; i++)if(bzy[i] && wc[i]) printf(" c%d" , i);cout<<endl; } return 0;}
0 0
- uva 11419最小点覆盖和…
- UVa 11419 二分图最小点覆盖
- uva 11419(最大匹配,最小点覆盖)
- Uva 11419 SAM I AM (最小点覆盖)
- UVA 11419 SAM I AM(最小点覆盖)
- UVA 11419SAM I AM (最小点覆盖)
- UVA 11419 SAM I AM 二分匹配最小覆盖点
- UVA 11419 SAM I AM 二分图+最小覆盖点
- UVA 11419 SAM I AM (最小点覆盖)
- Uva - 11419 - SAM I AM(二分图最小点覆盖)
- UVA 11419 SAM I AM(二分图最小点覆盖)
- uva 11419 SAM I AM 求出二分图的最小点覆盖集
- UVA 11419 - SAM I AM(二分图匹配+最小点覆盖)
- UVa 11419 二分图最小点覆盖 续写 好题
- UVa 11419 SAM I AM (最小点覆盖,匈牙利算法)
- Uva 1292 - Strategic game 树形dp 最小点覆盖
- UVA 12549 Sentry Robots 最小点集覆盖
- uva 11419 二部图 【求最小覆盖】
- 求强连通分量几种算法的比较
- poj 3207 简单的2-SAT问题
- zoj 1654 中等二分匹配
- poj 2195 最优匹配算法的优化
- poj 2771 有点难度最大独立集
- uva 11419最小点覆盖和…
- poj 3522 MST性质的运用
- MST中求任意两点条路径上的最长边…
- uva 1265 (LA 4848)
- poj 2793 有难度的点连通分量应用
- poj 2662 最短路算法的扩展应用
- hdu 4725 有点深度的最短路
- hdu 4738 2013杭州网络赛一题
- uva 10603 状态压缩& 最短路