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 }

 

 

posted @ 2013-02-21 21:58  silver__bullet  阅读(710)  评论(0编辑  收藏  举报