Uva 11419 SAM I AM
解法:
二分图的模型显而易见,而且对于一个不含孤立点的二分图,最小点覆盖数=最大匹配数。问题要求输出一个最小点覆盖集,我们可以在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集。具体的讲解可以看这个
p.s.代码写的太丑了~~~~(>_<)~~~~
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #define N 1010 6 using namespace std; 7 struct Edge{ 8 int u,v,next; 9 Edge(){} 10 Edge(int _u,int _v,int _next){ 11 u=_u;v=_v;next=_next; 12 } 13 }edge[N*N]; 14 int head[N],cnt; 15 int mat[N]; 16 int cx[N],cy[N]; 17 int hx[N],hy[N]; 18 bool vx[N],vy[N]; 19 map<int,int>mx,my; 20 int x,y; 21 void init(){ 22 memset(head,-1,sizeof(head)); 23 cnt=0; 24 mx.clear();x=0; 25 my.clear();y=0; 26 } 27 void add(int u,int v){ 28 edge[cnt]=Edge(u,v,head[u]);head[u]=cnt++; 29 // edge[cnt]=Edge(v,u,head[v]);head[v]=cnt++; 30 } 31 bool find(int u){ 32 for(int k=head[u];k!=-1;k=edge[k].next){ 33 int v=edge[k].v; 34 if(vy[v])continue; 35 vy[v]=1; 36 if(cy[v]==-1||find(cy[v])){ 37 cx[u]=v; 38 cy[v]=u; 39 return 1; 40 } 41 } 42 return 0; 43 } 44 void dfs(int u){ 45 vx[u]=1; 46 for(int k=head[u];k!=-1;k=edge[k].next){ 47 int v=edge[k].v; 48 if(vy[v])continue; 49 vy[v]=1; 50 dfs(cy[v]); 51 } 52 } 53 int solve(){ 54 memset(cx,-1,sizeof(cx)); 55 memset(cy,-1,sizeof(cy)); 56 int ans=0; 57 for(int i=1;i<=x;i++){ 58 if(cx[i]==-1){ 59 memset(vy,0,sizeof(vy)); 60 ans+=find(i); 61 } 62 } 63 memset(vx,0,sizeof(vx)); 64 memset(vy,0,sizeof(vy)); 65 for(int i=1;i<=x;i++) 66 if(cx[i]==-1&&vx[i]==0)dfs(i); 67 return ans; 68 } 69 int main(){ 70 int r,c,n; 71 while(~scanf("%d%d%d",&r,&c,&n)){ 72 if(!(r||c||n))return 0; 73 init(); 74 for(int i=1;i<=n;i++){ 75 int u,v; 76 scanf("%d%d",&u,&v); 77 if(!mx.count(u)){ 78 mx[u]=++x; 79 hx[x]=u; 80 } 81 if(!my.count(v)){ 82 my[v]=++y; 83 hy[y]=v; 84 } 85 add(mx[u],my[v]); 86 } 87 int ans=solve(); 88 printf("%d",ans); 89 for(int i=1;i<=x;i++) 90 if(!vx[i])printf(" r%d",hx[i]); 91 for(int i=1;i<=y;i++) 92 if(vy[i])printf(" c%d",hy[i]); 93 printf("\n"); 94 } 95 return 0; 96 }