首页 > 代码库 > 二分图最小覆盖

二分图最小覆盖

hdu1150 

最小顶点覆盖

 

hdu1498 50 years, 50 colors

最小顶点覆盖 +枚举

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 105
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 vector<int>ed[N];
18 struct node
19 {
20     int x,y;
21 };
22 vector<node>pa[N];
23 bool vis[2*N],f[N];
24 int mat[N<<1],o[N],co[N];
25 int dfs(int u)
26 {
27     int i;
28     for(i = 0 ;i < ed[u].size() ; i++)
29     {
30         int v = ed[u][i];
31         if(vis[v]) continue;
32         vis[v] = 1;
33         if(mat[v]==-1||dfs(mat[v]))
34         {
35             mat[v] = u;
36             return 1;
37         }
38     }
39     return 0;
40 }
41 int main()
42 {
43     int n,k,i,j;
44     while(scanf("%d%d",&n,&k)&&n&&k)
45     {
46         memset(f,0,sizeof(f));
47         for(i = 1; i <=100 ;i++)
48         pa[i].clear();
49         int m = 0 ;
50         for(i = 1; i <= n ;i++)
51             for(j = 1 ;j <= n ;j++)
52             {
53                 int x;
54                 node a;
55                 a.x = i;a.y = j;
56                 scanf("%d",&x);
57                 if(!f[x])
58                 {
59                     f[x] = 1;
60                     m++;
61                     co[m] = x;
62                 }
63                 pa[x].push_back(a);
64             }
65         int g = 0;
66         for(i = 1; i <= m; i++)
67         {
68             memset(mat,-1,sizeof(mat));
69             int c = co[i];
70             for(j = 1; j <= n; j++)
71             ed[j].clear();
72             for(j = 0 ;j < pa[c].size() ; j++)
73             {
74                 node a = pa[c][j];
75                 ed[a.x].push_back(a.y+n);
76             }
77             int cnt = 0;
78             for(j = 1; j <= n ;j++)
79             {
80                 memset(vis,0,sizeof(vis));
81                 if(dfs(j))
82                 cnt++;
83             }
84             if(cnt>k)
85             o[++g] = c;
86         }
87         if(g==0)
88         {
89             puts("-1");
90             continue;
91         }
92         sort(o+1,o+g+1);
93         for(i =1 ;i < g ; i++)
94         cout<<o[i]<<" ";
95         cout<<o[i]<<endl;
96     }
97     return 0;
98 }
View Code

 

 

hdu2119  

最小顶点覆盖 裸

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 110
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 vector<int>ed[N];
18 bool vis[N<<1];
19 int mat[N<<1];
20 int dfs(int u)
21 {
22     int i;
23     for(i = 0 ;i < ed[u].size();  i++)
24     {
25         int v = ed[u][i];
26         if(vis[v]) continue;
27         vis[v] = 1;
28         if(mat[v]==-1||dfs(mat[v]))
29         {
30             mat[v] = u;
31             return 1;
32         }
33     }
34     return 0;
35 }
36 
37 int main()
38 {
39     int n,i,j,m;
40     while(cin>>n)
41     {
42         if(!n) break;
43         cin>>m;
44         memset(mat,-1,sizeof(mat));
45         for(i = 1 ;i <=  n;i++)
46         ed[i].clear();
47         for(i = 1 ;i <= n ;i++)
48             for(j = 1 ;j <= m ;j++)
49             {
50                 int x;
51                 cin>>x;
52                 if(x)
53                 ed[i].push_back(j+n);
54             }
55         int ans = 0;
56         for(i = 1 ;i <= n;i++)
57         {
58             memset(vis,0,sizeof(vis));
59             if(dfs(i))
60             ans++;
61         }
62         cout<<ans<<endl;
63     }
64     return 0;
65 }
View Code

 

 

hdu1054  Strategic Game

最小顶点覆盖 不确定左右子集 建双向边 答案/2

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 1510
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int mat[N];
18 bool vis[N];
19 vector<int>ed[N];
20 int dfs(int u)
21 {
22     int i;
23     for(i = 0; i < ed[u].size(); i++)
24     {
25         int v = ed[u][i];
26         if(vis[v]) continue;
27         vis[v] = 1;
28         if(mat[v]==-1||dfs(mat[v]))
29         {
30             mat[v] = u;
31             return 1;
32         }
33     }
34     return 0;
35 }
36 int main()
37 {
38     int n,i;
39     while(scanf("%d",&n)!=EOF)
40     {
41         memset(mat,-1,sizeof(mat));
42         memset(vis,0,sizeof(vis));
43         for(i = 0 ; i < n; i++)
44         ed[i].clear();
45         for(i = 0 ; i < n ;i++)
46         {
47             int u,v,k;
48             scanf("%d%*c%*c%d%*c",&u,&k);
49             while(k--)
50             {
51                 scanf("%d",&v);
52                 ed[u].push_back(v);
53                 ed[v].push_back(u);
54             }
55         }
56         int ans  =0;
57         for(i = 0 ;i < n ;i++)
58         {
59             memset(vis,0,sizeof(vis));
60             if(dfs(i))
61             ans++;
62         }
63         printf("%d\n",ans/2);
64     }
65     return 0;
66 }
View Code

 

 

 

hdu1151   Air Raid

最小路径覆盖 裸

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<queue>
 8 #include<cmath>
 9 using namespace std;
10 #define N 1010
11 vector<int>pa[N];
12 bool fx[N],fy[N];
13 int vis[N],mat[N];
14 int find(int u)
15 {
16     int i;
17     for(i = 0 ; i < (int)pa[u].size() ; i++)
18     {
19         int v = pa[u][i];
20         if(vis[v]) continue;
21         vis[v] = 1;
22         if(mat[v]==0||find(mat[v]))
23         {
24             mat[v] = u;
25             return 1;
26         }
27     }
28     return 0;
29 }
30 int main()
31 {
32     int n,m,i,t;
33     scanf("%d",&t);
34     while(t--)
35     {
36         scanf("%d%d",&n,&m);
37         memset(mat,0,sizeof(mat));
38         for(i = 1; i <= 1000 ; i++)
39         pa[i].clear();
40         for(i = 1; i <= m ;i++)
41         {
42             int v,u;
43             scanf("%d%d",&u,&v);
44             pa[u].push_back(v+n);
45         }
46         int s = 0;
47         for(i = 1; i <= n ;i++)
48         {
49             memset(vis,0,sizeof(vis));
50             if(find(i))
51             s++;
52         }
53         printf("%d\n",n-s);
54     }
55     return 0;
56 }
View Code

 

 

hdu1350 Taxi Cab Scheme

最小路径覆盖 

根据时间限制建边 注意:当前结束点与下一个开始点不同也可以建边 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 510
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 vector<int>ed[N];
18 int ma[N][N],mat[N];
19 bool vis[N];
20 struct node
21 {
22     int t,u,v;
23     int u1,u2,v1,v2;
24     int d;
25 }p[N];
26 int dfs(int u)
27 {
28     int i;
29     for(i = 0; i < ed[u].size() ; i++)
30     {
31         int v = ed[u][i];
32         if(vis[v]) continue;
33         vis[v] = 1;
34         if(mat[v]==-1||dfs(mat[v]))
35         {
36             mat[v] = u;
37             return 1;
38         }
39     }
40     return 0;
41 }
42 int main()
43 {
44     int n,m,i,j;
45     int mod = 24*60;
46     cin>>n;
47     while(n--)
48     {
49         cin>>m;
50         memset(ma,0,sizeof(ma));
51         memset(mat,-1,sizeof(mat));
52         for(i = 1; i <= m ;i++)
53         ed[i].clear();
54         int g = 0;
55         for(i = 1; i<= m ;i++)
56         {
57             int x,y,u1,u2,v1,v2;
58             scanf("%d%*c%d%d%d%d%d",&x,&y,&p[i].u1,&p[i].v1,&p[i].u2,&p[i].v2);
59             /*if(!ma[u1][v1])
60             {
61                 g++;
62                 ma[u1][v1] = g;
63             }
64             if(!ma[u2][v2])
65             {
66                 g++;
67                 ma[u2][v2] = g;
68             }
69             p[i].u = ma[u1][v1],p[i].v = ma[u2][v2];*/
70             p[i].d = abs(p[i].u1-p[i].u2)+abs(p[i].v1-p[i].v2);
71             p[i].t = x*60+y;
72         }
73         for(i = 1 ;i <= m ;i++)
74         {
75             for(j = i+1 ;j <= m; j++)
76             {
77                 int tt = abs(p[i].u2-p[j].u1)+abs(p[i].v2-p[j].v1);
78                 if(p[i].t+p[i].d+tt<p[j].t)
79                 {
80                     ed[i].push_back(j);
81                 }
82             }
83         }
84         int ans = 0;
85         for(i = 1;i <= m ;i++)
86         {
87             memset(vis,0,sizeof(vis));
88             if(dfs(i))
89             ans++;
90         }
91         cout<<m-ans<<endl;
92     }
93     return 0;
94 }
View Code