PKU 3041 Asteroids - 行列的二分图模型 最小点覆盖
2008-11-21 22:37
453 查看
题目大意:
N*N的空间中有K个小行星,使用超级武器可以一次性清理一行或一列的所有小行星.但是超级武器很贵,给出星空图,问最少需要使用多少次武器能清除所有的小行星.N<500, k<10,000
分析:
很经典的行列模型转换为二分图模型来处理的题目,ZJU1002和PKU2226也是可以这样转换.
将行和列分别作为二分图左边和右边的节点.若在地图(i,j)上有一颗小行星,那么二分图左边i节点和右边j节点之间连一条边.
将此模型对应到题目上来,使用一次武器就是选择二分图上左边或右边的一个点v.和v相连的边,表示v行(或列)当中所有的小行星.那么题目的问题转换为了:在二分图中选择最少的点,使得所有的边都至少有一个端点被覆盖到.
这就是经典的二分图的最小点覆盖.
根据König定理:二分图 最小点覆盖数 = 最大匹配数.
所以题目转换为了求二分图的最大匹配,也就比较完美的解决了.
顺便说一句,ZJU1002的二分图模型的不能直接用行或列作为二分图的点,而是需要拆点.详细请看我的另一篇解题报告
http://blog.csdn.net/tiaotiaoyly/archive/2008/10/23/3122893.aspx
/*
PKU3041 Asteroids
*/
#include <stdio.h>
#include <memory.h>
#define clr(a) memset(a,0,sizeof(a))
#define N 505
int find(int i,int m,int g[]
,int mat[],int tmat[]){
int v,j;
for(j=0;j<m;j++){
if(g[i][j]&&tmat[j]==0){
tmat[j]=1; v=mat[j]; mat[j]=i;
if(v==-1||find(v,m,g,mat,tmat)) return 1;
mat[j]=v;
}
}
return 0;
}
int match(int g[]
,int n,int m,int mat[]){
int i,k=0,tmat
;
for(i=0;i<m;i++) mat[i]=-1;
for(i=0;i<n;i++){
clr(tmat); k+=find(i,m,g,mat,tmat);
}
return k;
}
int n,m;
int a
;
int mat
;
int main()
{
int i,j,k;
while(scanf("%d%d",&n,&m)!=EOF){
//init
clr(a);
//input
for(k=0;k<m;k++){
scanf("%d%d",&i,&j);
i--; j--;
a[i][j]=1;
}
//output
k=match(a,n,n,mat);
printf("%d/n",k);
}
return 0;
}
N*N的空间中有K个小行星,使用超级武器可以一次性清理一行或一列的所有小行星.但是超级武器很贵,给出星空图,问最少需要使用多少次武器能清除所有的小行星.N<500, k<10,000
分析:
很经典的行列模型转换为二分图模型来处理的题目,ZJU1002和PKU2226也是可以这样转换.
将行和列分别作为二分图左边和右边的节点.若在地图(i,j)上有一颗小行星,那么二分图左边i节点和右边j节点之间连一条边.
将此模型对应到题目上来,使用一次武器就是选择二分图上左边或右边的一个点v.和v相连的边,表示v行(或列)当中所有的小行星.那么题目的问题转换为了:在二分图中选择最少的点,使得所有的边都至少有一个端点被覆盖到.
这就是经典的二分图的最小点覆盖.
根据König定理:二分图 最小点覆盖数 = 最大匹配数.
所以题目转换为了求二分图的最大匹配,也就比较完美的解决了.
顺便说一句,ZJU1002的二分图模型的不能直接用行或列作为二分图的点,而是需要拆点.详细请看我的另一篇解题报告
http://blog.csdn.net/tiaotiaoyly/archive/2008/10/23/3122893.aspx
/*
PKU3041 Asteroids
*/
#include <stdio.h>
#include <memory.h>
#define clr(a) memset(a,0,sizeof(a))
#define N 505
int find(int i,int m,int g[]
,int mat[],int tmat[]){
int v,j;
for(j=0;j<m;j++){
if(g[i][j]&&tmat[j]==0){
tmat[j]=1; v=mat[j]; mat[j]=i;
if(v==-1||find(v,m,g,mat,tmat)) return 1;
mat[j]=v;
}
}
return 0;
}
int match(int g[]
,int n,int m,int mat[]){
int i,k=0,tmat
;
for(i=0;i<m;i++) mat[i]=-1;
for(i=0;i<n;i++){
clr(tmat); k+=find(i,m,g,mat,tmat);
}
return k;
}
int n,m;
int a
;
int mat
;
int main()
{
int i,j,k;
while(scanf("%d%d",&n,&m)!=EOF){
//init
clr(a);
//input
for(k=0;k<m;k++){
scanf("%d%d",&i,&j);
i--; j--;
a[i][j]=1;
}
//output
k=match(a,n,n,mat);
printf("%d/n",k);
}
return 0;
}
相关文章推荐
- POJ 3041 Asteroids 二分图最小点覆盖
- POJ训练计划3041_Asteroids(二分图/最小点覆盖=最大匹配)
- POJ-3041-Asteroids(二分图最小点覆盖)
- poj 3041 Asteroids 二分图最小点覆盖
- poj 3041 Asteroids(二分图最小顶点覆盖)
- 【POJ 3041 】Asteroids (匈牙利算法最小点覆盖&二分图)
- 行列的二分图模型 最小点覆盖——pku3041
- POJ 3041 Asteroids 最小点覆盖 == 二分图的最大匹配
- pku 3041 Asteroids 二分图匹配——匈牙利算法求最小点覆盖
- poj2226(*行列模型,二分图最小顶点覆盖)
- POJ训练计划3041_Asteroids(二分图/最小点覆盖=最大匹配)
- pku3041-Asteroids 最小点覆盖
- POJ 3041 Asteroids 二分图 最小点覆盖
- POJ 3041 Asteroids (二分图最小点覆盖)
- poj 3041 Asteroids (二分图最大匹配 == 最小点覆盖数)
- POJ 3041-Asteroids(二分图最小顶点覆盖)
- POJ - 3041 Asteroids 二分图 最小点覆盖
- poj 3041 Asteroids( 最小顶点覆盖,二分图)
- POJ 3041--Asteroids【二分图 && 最小点数覆盖】
- pku 3041 Asteroids(最小点覆盖,最大二分匹配)