您的位置:首页 > 其它

Uva 11419 SAM I AM

2013-02-21 21:58 155 查看
解法:

  二分图的模型显而易见,而且对于一个不含孤立点的二分图,最小点覆盖数=最大匹配数。问题要求输出一个最小点覆盖集,我们可以在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集。具体的讲解可以看这个

p.s.代码写的太丑了~~~~(>_<)~~~~

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define N 1010
using namespace std;
struct Edge{
int u,v,next;
Edge(){}
Edge(int _u,int _v,int _next){
u=_u;v=_v;next=_next;
}
}edge[N*N];
int head
,cnt;
int mat
;
int cx
,cy
;
int hx
,hy
;
bool vx
,vy
;
map<int,int>mx,my;
int x,y;
void init(){
memset(head,-1,sizeof(head));
cnt=0;
mx.clear();x=0;
my.clear();y=0;
}
void add(int u,int v){
edge[cnt]=Edge(u,v,head[u]);head[u]=cnt++;
//    edge[cnt]=Edge(v,u,head[v]);head[v]=cnt++;
}
bool find(int u){
for(int k=head[u];k!=-1;k=edge[k].next){
int v=edge[k].v;
if(vy[v])continue;
vy[v]=1;
if(cy[v]==-1||find(cy[v])){
cx[u]=v;
cy[v]=u;
return 1;
}
}
return 0;
}
void dfs(int u){
vx[u]=1;
for(int k=head[u];k!=-1;k=edge[k].next){
int v=edge[k].v;
if(vy[v])continue;
vy[v]=1;
dfs(cy[v]);
}
}
int solve(){
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
int ans=0;
for(int i=1;i<=x;i++){
if(cx[i]==-1){
memset(vy,0,sizeof(vy));
ans+=find(i);
}
}
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
for(int i=1;i<=x;i++)
if(cx[i]==-1&&vx[i]==0)dfs(i);
return ans;
}
int main(){
int r,c,n;
while(~scanf("%d%d%d",&r,&c,&n)){
if(!(r||c||n))return 0;
init();
for(int i=1;i<=n;i++){
int u,v;
scanf("%d%d",&u,&v);
if(!mx.count(u)){
mx[u]=++x;
hx[x]=u;
}
if(!my.count(v)){
my[v]=++y;
hy[y]=v;
}
add(mx[u],my[v]);
}
int ans=solve();
printf("%d",ans);
for(int i=1;i<=x;i++)
if(!vx[i])printf(" r%d",hx[i]);
for(int i=1;i<=y;i++)
if(vy[i])printf(" c%d",hy[i]);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: