二分图最大匹配

hdu1179 

Ollivanders: Makers of Fine Wands since 382 BC.

裸最大匹配

 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 棋盘游戏
二分匹配+枚举

 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*

连边 最大匹配

  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 过山车

裸最大匹配

 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
通过大小建边

 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染色判是不是二分图 然后求最大匹配

 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

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

 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

把区间拆成点 建边

 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算法 

  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

 

 

 

你可能感兴趣的:(二分图)