码迷,mamicode.com
首页 > 其他好文 > 详细

二分图最大匹配

时间:2014-05-08 14:49:37      阅读:511      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   code   tar   color   

hdu1179 

Ollivanders: Makers of Fine Wands since 382 BC.

裸最大匹配

bubuko.com,布布扣
 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 bool vis[2*N];
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 int main()
37 {
38     int n,m,i,j;
39     while(scanf("%d%d",&n,&m)!=EOF)
40     {
41         //scanf("%d",&m);
42         memset(vis,0,sizeof(vis));
43         memset(mat,-1,sizeof(mat));
44         for(i = 1; i <= m; i++)
45         ed[i].clear();
46         for(i = 1; i <= m; i++)
47         {
48             int k;
49             scanf("%d",&k);
50             for(j = 1; j <= k; j++)
51             {
52                 int v;
53                 scanf("%d",&v);
54                 ed[i].push_back(v+m);
55             }
56         }
57         int ans = 0;
58         for(i = 1; i <= m; i++)
59         {
60             memset(vis,0,sizeof(vis));
61             if(dfs(i))
62             ans++;
63         }
64         cout<<ans<<endl;
65     }
66     return 0;
67 }
View Code

 

hdu1281 棋盘游戏
二分匹配+枚举

bubuko.com,布布扣
 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 205
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     int u,v;
20 }p[N*N];
21 bool vis[N];
22 int mat[N],pp[N];
23 int dfs(int u)
24 {
25     int i;
26     for(i = 0 ;i < ed[u].size() ; i++)
27     {
28         int v = ed[u][i];
29         if(vis[v]) continue;
30         vis[v] = 1;
31         if(mat[v]==-1||dfs(mat[v]))
32         {
33             mat[v] = u;
34             pp[u] = v;
35             return 1;
36         }
37     }
38     return 0;
39 }
40 int main()
41 {
42     int n,m,k,i;
43     int kk = 0;
44     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
45     {
46         memset(vis,0,sizeof(vis));
47         memset(mat,-1,sizeof(mat));
48         memset(pp,0,sizeof(pp));
49         for(i = 1; i <= n; i++)
50         ed[i].clear();
51         for(i = 1; i <= k ;i++)
52         {
53             scanf("%d%d",&p[i].u,&p[i].v);
54             p[i].v+=n;
55             ed[p[i].u].push_back(p[i].v);
56         }
57         int ans = 0,cnt=0;
58         for(i = 1; i <= n ; i++)
59         {
60             memset(vis,0,sizeof(vis));
61             if(dfs(i))
62             ans++;
63         }
64         for(i = 1; i <= k; i++)
65         {
66             if(mat[p[i].v]==p[i].u)
67             {
68                // cout<<i<<" "<<mat[p[i].v]<<" "<<p[i].v<<endl;
69                 mat[p[i].v] = -1;
70 
71             }
72             else continue;
73             vector<int>::iterator it;
74             for(it = ed[p[i].u].begin() ; it < ed[p[i].u].end() ; it++)
75             {
76                 if(*it==p[i].v)
77                 ed[p[i].u].erase(it);
78             }
79             memset(vis,0,sizeof(vis));
80             //memset(mat,-1,sizeof(mat));
81             if(!dfs(p[i].u))
82             {
83 
84                 //cout<<p[i].u<<" "<<p[i].v<<" "<<ed[p[i].u].size()<<endl;
85                 cnt++;
86                 mat[p[i].v] = p[i].u;
87             }
88             ed[p[i].u].push_back(p[i].v);
89         }
90         printf("Board %d have %d important blanks for %d chessmen.\n",++kk,cnt,ans);
91     }
92     return 0;
93 }
View Code

 

hdu1507 Uncle Tom‘s Inherited Land*

连边 最大匹配

bubuko.com,布布扣
  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],f[N][N];
 19 int mat[N<<1],p[N][N],w[N][N];
 20 int dis[4][2] = {0,1,1,0,0,-1,-1,0};
 21 int po[N][2];
 22 int dfs(int u)
 23 {
 24     int i;
 25     for(i = 0 ;i < ed[u].size();  i++)
 26     {
 27         int v = ed[u][i];
 28         if(vis[v]) continue;
 29         vis[v] = 1;
 30         if(mat[v]==-1||dfs(mat[v]))
 31         {
 32             mat[v] = u;
 33             return 1;
 34         }
 35     }
 36     return 0;
 37 }
 38 int main()
 39 {
 40     int n,m,k,i,j;
 41     while(cin>>n>>m)
 42     {
 43         if(!n&&!m) break;
 44         cin>>k;
 45         memset(mat,-1,sizeof(mat));
 46         memset(p,0,sizeof(p));
 47         memset(f,0,sizeof(f));
 48         memset(w,0,sizeof(w));
 49         for(i = 1 ;i <= k ;i++)
 50         {
 51             int x,y;
 52             scanf("%d%d",&x,&y);
 53             f[x][y] = 1;
 54         }
 55         int g = 0;
 56         for(i = 1; i <= n; i++)
 57             for(j = 1; j <= m ;j++)
 58             {
 59                 if(!f[i][j])
 60                 {
 61                     p[i][j] = ++g;
 62                     po[g][0] = i;
 63                     po[g][1] = j;
 64                 }
 65             }
 66         for(i = 1; i <= g; i++)
 67         ed[i].clear();
 68         for(i = 1; i <= n; i++)
 69             for(j = 1 ;j <= m;j++)
 70             {
 71                 if(!p[i][j]) continue;
 72                 for(int o = 0 ; o < 4 ;o++)
 73                 {
 74                     int tx = dis[o][0]+i;
 75                     int ty = dis[o][1]+j;
 76                     if(p[tx][ty])
 77                     {
 78                         ed[p[i][j]].push_back(p[tx][ty]);
 79                         //cout<<p[i][j]<<" "<<p[tx][ty]<<endl;
 80                         //w[p[i][j]][p[tx][ty]] = 1;
 81                     }
 82                 }
 83             }
 84         int ans = 0;
 85         for(i = 1 ;i <= g ;i++)
 86         {
 87             memset(vis,0,sizeof(vis));
 88             if(dfs(i))
 89             ans++;
 90         }
 91         cout<<ans/2<<endl;
 92         memset(vis,0,sizeof(vis));
 93         for(i = 1; i <= g ;i++)
 94         {
 95             if(mat[i]!=-1&&!vis[mat[i]])
 96             {
 97                 printf("(%d,%d)--(%d,%d)\n",po[i][0],po[i][1],po[mat[i]][0],po[mat[i]][1]);
 98                 vis[mat[i]] = 1;
 99                 vis[i] = 1;
100             }
101         }
102         puts("");
103     }
104     return 0;
105 }
View Code

 

hdu2063 过山车

裸最大匹配

bubuko.com,布布扣
 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 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 int main()
37 {
38     int n,m,k,i;
39     while(cin>>k)
40     {
41         if(!k) break;
42         cin>>n>>m;
43         memset(mat,-1,sizeof(mat));
44         for(i = 1; i <= n; i++)
45         ed[i].clear();
46         for(i  =1 ;i <=k ;i++)
47         {
48             int u,v;
49             cin>>u>>v;
50             ed[u].push_back(v+n);
51         }
52         int ans = 0;
53         for(i = 1; i <=n ;i++)
54         {
55             memset(vis,0,sizeof(vis));
56             if(dfs(i))
57             ans++;
58         }
59         cout<<ans<<endl;
60     }
61     return 0;
62 }
View Code

 

hdu1528  Card Game Cheater
通过大小建边

bubuko.com,布布扣
 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 char s[N][10],ss[N][10];
21 int d[200];
22 int dfs(int u)
23 {
24     int i;
25     for(i = 0 ;i < ed[u].size();  i++)
26     {
27         int v = ed[u][i];
28         if(vis[v]) continue;
29         vis[v] = 1;
30         if(mat[v]==-1||dfs(mat[v]))
31         {
32             mat[v] = u;
33             return 1;
34         }
35     }
36     return 0;
37 }
38 int judge(char *x,char *y)
39 {
40     if(d[x[0]]==d[y[0]])
41     {
42         return d[x[1]]<d[y[1]];
43     }
44     return d[x[0]]<d[y[0]];
45 }
46 int main()
47 {
48     int n,i,j,t;
49     d[H] = 4;
50     d[S] = 3;
51     d[D] = 2;
52     d[C] = 1;
53     for(i = 2; i <= 9 ;  i++)
54     d[i+0] = i;
55     d[T] = 10;
56     d[J] = 11;
57     d[Q] = 12;
58     d[K] = 13;
59     d[A] = 14;
60     cin>>t;
61     while(t--)
62     {
63         memset(mat,-1,sizeof(mat));
64         cin>>n;
65         for(i = 1;i <= n;i++)
66         ed[i].clear();
67         for(i = 1; i <= n ;i++)
68         cin>>s[i];
69         for(i = 1; i <= n ;i++)
70         cin>>ss[i];
71         for(i = 1; i <= n ;i++)
72             for(j = 1 ;j <= n ;j++)
73             if(judge(s[i],ss[j]))
74             {
75                 ed[i].push_back(j+n);
76                 //cout<<i<<" "<<j+n<<endl;
77             }
78         int ans = 0;
79         for(i = 1; i <= n ;i++)
80         {
81             memset(vis,0,sizeof(vis));
82             if(dfs(i))
83             ans++;
84         }
85         cout<<ans<<endl;
86     }
87     return 0;
88 }
View Code

 

 

hdu2444 The Accomodation of Students

dfs染色判是不是二分图 然后求最大匹配

bubuko.com,布布扣
 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 210
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 vis[N<<1];
19 int mat[N<<1];
20 int flag;
21 int dfs(int u)
22 {
23     int i;
24     for(i = 0 ;i < ed[u].size();  i++)
25     {
26         int v = ed[u][i];
27         if(vis[v]) continue;
28         vis[v] = 1;
29         if(mat[v]==-1||dfs(mat[v]))
30         {
31             mat[v] = u;
32             return 1;
33         }
34     }
35     return 0;
36 }
37 void find(int u)
38 {
39     int i;
40     for(i = 0 ; i < ed[u].size() ; i++)
41     {
42         int v = ed[u][i];
43         if(vis[v]&&vis[v]!=-vis[u])
44         {
45             flag = 1;
46             break;
47         }
48         if(vis[v]) continue;
49         vis[v] = -vis[u];
50         find(v);
51     }
52 }
53 int main()
54 {
55     int n,i,m;
56     while(cin>>n>>m)
57     {
58         memset(mat,-1,sizeof(mat));
59         memset(vis,0,sizeof(vis));
60         for(i = 1 ;i <= n;i++)
61         ed[i].clear();
62         for(i = 1 ;i <= m ;i++)
63         {
64             int u,v;
65             cin>>u>>v;
66             ed[u].push_back(v);
67             //ed[v].push_back(u);
68         }
69         flag = 0;
70         for(i = 1; i <= n ; i++)
71         {
72             if(!vis[i])
73             {
74                 vis[i] = 1;
75                 find(i);
76             }
77             if(flag)
78             break;
79         }
80         if(flag)
81         {
82             puts("No");
83             continue;
84         }
85        // memset(vis,0,sizeof(vis));
86         int ans = 0;
87         for(i = 1 ;i <= n;i++)
88         {
89             memset(vis,0,sizeof(vis));
90             if(dfs(i))
91             ans++;
92         }
93         cout<<ans<<endl;
94     }
95     return 0;
96 }
View Code

 

hdu1045 Fire Net

将隔板隔开的行和列拆成多个点 建边

bubuko.com,布布扣
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<stdlib.h>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 #define N 6152
10 bool vis[N<<2];
11 int mat[N<<2];
12 vector<int>ed[N];
13 char s[110][110];
14 int p[110][110][2];
15 int dfs(int u)
16 {
17     int i;
18     for(i = 0;i < ed[u].size() ; i++)
19     {
20         int v = ed[u][i];
21         if(vis[v]) continue;
22         vis[v] = 1;
23         if(mat[v]==-1||dfs(mat[v]))
24         {
25             mat[v] = u;
26             return 1;
27         }
28     }
29     return 0;
30 }
31 int main()
32 {
33     int n,i,j;
34     while(cin>>n)
35     {
36         if(!n) break;
37         memset(mat,-1,sizeof(mat));
38         for(i = 1; i <= n;i++)
39         {
40             getchar();
41             for(j  = 1 ;j <= n;j++)
42             scanf("%c",&s[i][j]);
43         }
44         int o = 0;
45         for(i = 1; i <=n ;i++)
46         {
47             int f = 0;
48             ++o;
49             for(j = 1; j <= n ;j++)
50             {
51                 if(f&&s[i][j]==X)
52                 {
53                     o++;
54                     f = 0;
55                 }
56                 else if(s[i][j]!=X)
57                 {
58                     p[i][j][0] = o;
59                     f = 1;
60                 }
61             }
62         }
63         int oo = o;
64         for(i = 1; i <= oo ; i++)
65         ed[i].clear();
66         for(j = 1; j <= n ;j++)
67         {
68             int f = 0;
69             ++o;
70             for(i = 1; i <= n; i++)
71             {
72                 if(f&&s[i][j]==X)
73                 {
74                     f = 0;
75                     o++;
76                 }
77                 else if(s[i][j]!=X)
78                 {
79                     f = 1;
80                     p[i][j][1] = o;
81                 }
82             }
83         }
84         for(i = 1; i <= n; i++)
85             for(j = 1; j <= n; j++)
86             if(s[i][j]!=X)
87             ed[p[i][j][0]].push_back(p[i][j][1]);
88         int ans = 0;
89         for(i = 1 ; i <= oo ; i++)
90         {
91             for(j = 1 ; j <= o ;j ++)
92             vis[j] = 0;
93             if(dfs(i))
94             ans++;
95         }
96         cout<<ans<<endl;
97     }
98     return 0;
99 }
View Code

 

 

hdu3729 I‘m Telling the Truth

把区间拆成点 建边

bubuko.com,布布扣
 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 LL long long
12 #define INF 0xfffffff
13 #define N 66
14 #define M 100666
15 const double eps = 1e-8;
16 const double pi = acos(-1.0);
17 const double inf = ~0u>>2;
18 vector<int>ed[N];
19 bool vis[M];
20 int mat[M],o[N];
21 int dfs(int u)
22 {
23     int i;
24     for(i = 0;i < ed[u].size() ; i++)
25     {
26         int v = ed[u][i];
27         if(vis[v]) continue;
28         vis[v] = 1;
29         if(mat[v] == -1||dfs(mat[v]))
30         {
31             mat[v] = u;
32             return 1;
33         }
34     }
35     return 0;
36 }
37 int main()
38 {
39     int n,x,y,t,i,j;
40     cin>>t;
41     while(t--)
42     {
43         memset(mat,-1,sizeof(mat));
44         cin>>n;
45         for(i = 1; i <= n; i++)
46         ed[i].clear();
47         for(i = 1 ;i <= n; i++)
48         {
49             cin>>x>>y;
50             x+=n,y+=n;
51             for(j = x ; j <= y ; j++)
52             ed[i].push_back(j);
53         }
54         int ans = 0;
55         for(i = n; i >= 1 ; i--)
56         {
57             memset(vis,0,sizeof(vis));
58             if(dfs(i))
59             {
60                 ans++;
61                 o[ans] = i;
62             }
63         }
64         cout<<ans<<endl;
65         for(i = ans; i > 1 ; i--)
66         cout<<o[i]<<" ";
67         cout<<o[1]<<endl;
68     }
69     return 0;
70 }
View Code

 

 

hdu2389 Rain on your Parade(hk)

通过距离建边 复杂度比较高 需要用hk算法 

bubuko.com,布布扣
  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 100000
 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 xlink[N],ylink[N];
 19 bool vis[N];
 20 int dx[N],dy[N];
 21 int dis,n;
 22 struct node
 23 {
 24     int x,y,v;
 25 }p[N],u[N];
 26 void init()
 27 {
 28     memset(xlink,-1,sizeof(xlink));
 29     memset(ylink,-1,sizeof(ylink));
 30 }
 31 int bfs()
 32 {
 33     memset(dx,-1,sizeof(dx));
 34     memset(dy,-1,sizeof(dy));
 35     int i;
 36     queue<int>q;
 37     dis = INF;
 38     for(i = 1 ; i <= n;i++)
 39     if(xlink[i]==-1)
 40     {
 41         q.push(i);
 42         dx[i] = 0;
 43     }
 44     while(!q.empty())
 45     {
 46         int u = q.front(); q.pop();
 47         if(dx[u]>dis) break;
 48         for(i = 0 ;i < ed[u].size() ; i++)
 49         {
 50             int v = ed[u][i];
 51             if(dy[v]==-1)
 52             {
 53                 dy[v] = dx[u]+1;
 54                 if(ylink[v]==-1) dis = dy[v];
 55                 else
 56                 {
 57                     dx[ylink[v]] = dy[v]+1;
 58                     q.push(ylink[v]);
 59                 }
 60             }
 61         }
 62         //cout<<u<<endl;
 63     }
 64     return dis!=INF;
 65 }
 66 int find(int u)
 67 {
 68     int i;
 69     for(i = 0;i < ed[u].size() ; i++)
 70     {
 71         int v = ed[u][i];
 72 
 73         if(vis[v]||dy[v]!=dx[u]+1) continue;
 74         vis[v] = 1;
 75         if(ylink[v] != -1&&dy[v]==dis) continue;
 76         //cout<<ylink[v]<<" "<<u<<endl;
 77         if(ylink[v]==-1||find(ylink[v])) {
 78             ylink[v] = u;
 79             xlink[u] = v;
 80             return 1;
 81         }
 82     }
 83     return 0;
 84 }
 85 int hk()
 86 {
 87     int ans = 0,i;
 88     while(bfs())
 89     {
 90 
 91         memset(vis,0,sizeof(vis));
 92         for(i = 1 ; i <= n ;i++)
 93         {
 94             if(xlink[i]==-1)
 95             ans+=find(i);
 96         }
 97     }
 98     return ans;
 99 }
100 int main()
101 {
102     int t,T,m,i,j;
103     cin>>T;
104     int kk = 0;
105     while(T--)
106     {
107         init();
108         scanf("%d",&t);
109         scanf("%d",&n);
110         for(i = 1; i <= n ;i++)
111         ed[i].clear();
112         for(i = 1; i <= n ;i++)
113         {
114             scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].v);
115         }
116         scanf("%d",&m);
117         for(i = 1; i <= m ;i++)
118         scanf("%d%d",&u[i].x,&u[i].y);
119         for(i = 1; i <= n ;i++)
120             for(j = 1; j <= m;j++)
121             {
122                 int dis = (p[i].x-u[j].x)*(p[i].x-u[j].x)+(p[i].y-u[j].y)*(p[i].y-u[j].y);
123                 if((p[i].v*t)*(p[i].v*t)>=dis)
124                 {
125                     ed[i].push_back(j);
126                 }
127             }
128         printf("Scenario #%d:\n%d\n\n",++kk,hk());
129     }
130     return 0;
131 }
View Code

 

 

 

二分图最大匹配,布布扣,bubuko.com

二分图最大匹配

标签:style   blog   class   code   tar   color   

原文地址:http://www.cnblogs.com/shangyu/p/3715906.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!