hdu 3605 二分图多重匹配
和上一题大同小异,不过数据稍微强点。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int X = 100000; 7 const int Y = 10; 8 int head[X]; 9 int sz[Y]; 10 int cnt[Y]; 11 int mark[Y][X]; 12 bool visit[Y]; 13 int e; 14 15 void init() 16 { 17 e = 0; 18 memset( head, -1, sizeof(head) ); 19 } 20 21 struct Edge 22 { 23 int v, next; 24 } edge[X * Y]; 25 26 void addEdge( int u, int v ) 27 { 28 edge[e].v = v; 29 edge[e].next = head[u]; 30 head[u] = e++; 31 } 32 33 int dfs( int u ) 34 { 35 for ( int i = head[u]; i != -1; i = edge[i].next ) 36 { 37 int v = edge[i].v; 38 if ( !visit[v] ) 39 { 40 visit[v] = 1; 41 if ( cnt[v] < sz[v] ) 42 { 43 mark[v][cnt[v]++] = u; 44 return 1; 45 } 46 else 47 { 48 for ( int j = 0; j < cnt[v]; j++ ) 49 { 50 if ( dfs( mark[v][j] ) ) 51 { 52 mark[v][j] = u; 53 return 1; 54 } 55 } 56 } 57 } 58 } 59 return 0; 60 } 61 62 int main () 63 { 64 int n, m; 65 while ( scanf("%d%d", &n, &m) != EOF ) 66 { 67 init(); 68 for ( int i = 0; i < n; i++ ) 69 { 70 for ( int j = 0; j < m; j++ ) 71 { 72 int sn; 73 scanf("%d", &sn); 74 if ( sn ) 75 { 76 addEdge( i, j ); 77 } 78 } 79 } 80 for ( int i = 0; i < m; i++ ) 81 { 82 scanf("%d", sz + i); 83 } 84 memset( cnt, 0, sizeof(cnt) ); 85 bool flag = true; 86 for ( int i = 0; i < n; i++ ) 87 { 88 memset( visit, 0, sizeof(visit) ); 89 if ( !dfs(i) ) 90 { 91 flag = false; 92 break; 93 } 94 } 95 if ( flag ) 96 { 97 puts("YES"); 98 } 99 else 100 { 101 puts("NO"); 102 } 103 } 104 return 0; 105 }