HDU 1083

HDU 1083 http://acm.hdu.edu.cn/showproblem.php?pid=1083

PKU 1469 http://poj.org/problem?id=1469

【二分匹配】

网络流版本:

HDU 1083
1 //只要求出course的最大匹配数,再跟P比较即可.网络流实现
2  #include <iostream>
3 #include <cstdio>
4 #include <string>
5 #include <cstring>
6 #include <algorithm>
7 #include <vector>
8 #include <map>
9 #include <queue>
10
11  using namespace std;
12
13 const int MAXN=100+300+10;
14 int Flow[MAXN][MAXN];
15 int Vis[MAXN];
16 int Path[MAXN];
17 void creat_net(vector<int> box[], int studentNum, int courseNum)
18 {
19 for( int i=1; i<=studentNum; ++i )
20 {
21 box[0].push_back(i);
22 }
23 for( int i=1; i<=courseNum; ++i )
24 {
25 box[i+studentNum].push_back(studentNum+courseNum+1);
26 }
27 }
28 int bfs_net(vector<int> box[], int s, int t)
29 {
30 memset(Flow, 0, sizeof(Flow));
31 bool isFind;
32 int ans=0;
33 Path[0]=-1;
34 while( 1 )
35 {
36 queue<int> que;
37 memset(Vis, 0, sizeof(Vis));
38 que.push(s);
39 Vis[s]=1;
40 isFind=false;
41 while( !que.empty() )
42 {
43 int from=que.front();
44 vector<int>::iterator ix=box[from].begin();
45 while( ix!=box[from].end() )
46 {
47 if( !Vis[*ix] && ((from<*ix && 1>Flow[from][*ix] )||(from>*ix && 0>Flow[from][*ix])) )
48 {
49 que.push(*ix);
50 Path[*ix]=from;
51 Vis[*ix]=1;
52 if( *ix==t )
53 {
54 isFind=true;
55 break;
56 }
57 }
58 ++ix;
59 }
60 if( isFind )
61 {
62 break;
63 }
64 que.pop();
65 }
66 if( isFind==false )
67 {
68 return ans;
69 }
70 int from=Path[t];
71 int to=t;
72 for( ; ; )
73 {
74 if( from==-1 )
75 {
76 break;
77 }
78 Flow[from][to]++;
79 Flow[to][from]--;
80 to=from;
81 from=Path[to];
82 }
83 ans++;
84 }
85 }
86 int main()
87 {
88 freopen("in.txt","r",stdin);
89 int Case, P, N, preNum, temp;
90 scanf("%d", &Case);
91 while( Case-- )
92 {
93 scanf("%d%d", &P, &N);
94 vector<int> box[P+N+2];
95 for( int i=1; i<=P; ++i )
96 {
97 scanf("%d", &preNum);
98 for( int j=1; j<=preNum; ++j )
99 {
100 scanf("%d", &temp);
101 box[i+N].push_back(temp);
102 box[temp].push_back(i+N);
103 }
104 }
105 creat_net(box, N, P);
106 printf(bfs_net(box,0,P+N+1)==P?"YES\n":"NO\n");
107 }
108 return 0;
109 }
110
111

匈牙利算法:

代码
1 //匈牙利算法模版.
2  #include <iostream>
3 #include <algorithm>
4 #include <cstdio>
5 #include <cstring>
6
7 using namespace std;
8
9 const int MAXN=301;
10 const int INF=0x7f7f7f7f;
11 int P, N;
12 int Cap[MAXN][MAXN];
13 int Vis[MAXN];
14 int Match[MAXN];
15
16 bool dfs( int from )
17 {
18 for( int i=1; i<=P; ++i )
19 {
20 if( Cap[from][i] && !Vis[i] )
21 {
22 Vis[i]=1;
23 int temp=Match[i];
24 Match[i]=from;
25 if( temp==INF || dfs(temp) )
26 {
27 return true;
28 }
29 Match[i]=temp;
30 }
31 }
32 return false;
33 }
34 int main()
35 {
36 freopen("in","r",stdin);
37 freopen("out","w",stdout);
38
39 int t, num, temp;
40 scanf("%d", &t);
41 while( t-- )
42 {
43 memset(Cap, 0, sizeof(Cap));
44 scanf("%d%d", &P, &N);
45 for( int i=1; i<=P; ++i )
46 {
47 scanf("%d", &num);
48 while( num-- )
49 {
50 scanf("%d", &temp);
51 Cap[temp][i]=1;
52 }
53 }
54 int ans=0;
55 memset(Match, 0x7f, sizeof(Match));
56 for( int i=1; i<=N; ++i )
57 {
58 memset(Vis, 0, sizeof(Vis));
59 if( dfs(i) )
60 {
61 ans++;
62 }
63 }
64 printf(ans==P?"YES\n":"NO\n");
65 }
66 return 0;
67 }
68
posted on 2010-11-03 15:50  Kenfly  阅读(612)  评论(0编辑  收藏  举报