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

你可能感兴趣的:(HDU)