poj 1698 二分图多重匹配

网络流解法:

容易想到将每一天看做一个点并和汇点连容量为1的边(因为一天只能做一件事情),每个电影看做一个点并和源点连容量为d的边(即几天可以完成),然后电影和对应天数连容量为1的边,求最大流判断是否满流即可。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 const int INF = 9999999;
  7 const int N = 400;
  8 const int M = 20000;
  9 int head[N];
 10 int level[N];
 11 int q[N];
 12 int n, e, front, rear;
 13 
 14 void init()
 15 {
 16     e = 0;
 17     memset( head, -1, sizeof(head) );
 18 }
 19 
 20 struct Edge 
 21 {
 22     int v, next, cap;
 23 } edge[M];
 24 
 25 void addEdge( int u, int v, int cap )
 26 {
 27     edge[e].v = v;
 28     edge[e].cap = cap;
 29     edge[e].next = head[u];
 30     head[u] = e++;
 31     edge[e].v = u;
 32     edge[e].cap = 0;
 33     edge[e].next = head[v];
 34     head[v] = e++;
 35 }
 36 
 37 bool bfs( int s, int t )
 38 {
 39     front = rear = 0;
 40     memset( level, -1, sizeof(level) );
 41     q[rear++] = s;
 42     level[s] = 0;
 43     while ( front < rear )
 44     {
 45         int u = q[front++];
 46         for ( int i = head[u]; i != -1; i = edge[i].next )
 47         {
 48             int v = edge[i].v, cap = edge[i].cap;
 49             if ( level[v] == -1 && cap > 0 )
 50             {
 51                 level[v] = level[u] + 1;
 52                 q[rear++] = v;
 53             }
 54         }
 55     }
 56     return level[t] != -1;
 57 }
 58 
 59 int dfs( int u, int sum, int t )
 60 {
 61     if ( u == t ) return sum;
 62     int os = 0;
 63     for ( int i = head[u]; i != -1; i = edge[i].next )
 64     {
 65         int v = edge[i].v, cap = edge[i].cap;
 66         if ( level[v] == level[u] + 1 && cap > 0 )
 67         {
 68             int tt = dfs( v, min( sum, cap ), t );
 69             if ( tt == 0 ) continue;
 70             edge[i].cap -= tt;
 71             edge[i ^ 1].cap += tt;
 72             sum -= tt;
 73             os += tt;
 74             if ( sum == 0 ) break;
 75         }
 76     }
 77     if ( os == 0 ) level[u] = -1;
 78     return os;
 79 }
 80 
 81 int dinic( int s, int t )
 82 {
 83     int res = 0;
 84     while ( bfs( s, t ) )
 85     {
 86         res += dfs( s, INF, t );
 87     }
 88     return res;
 89 }
 90 
 91 const int D = 7;
 92 int nn[D];
 93 
 94 int main ()
 95 {
 96     int _case;
 97     scanf("%d", &_case);
 98     while ( _case-- )
 99     {
100         scanf("%d", &n);
101         init();
102         int tot = 0, wmax = -1, d, w;
103         for ( int i = 1; i <= n; i++ )
104         {
105             for ( int j = 0; j < D; j++ )
106             {
107                 scanf("%d", nn + j);
108             }
109             scanf("%d%d", &d, &w);
110             tot += d;
111             wmax = max( wmax, w );
112             addEdge( 0, i, d );
113             for ( int j = 0; j < D; j++ )
114             {
115                 if ( nn[j] == 1 )
116                 {
117                     for ( int k = 0; k < w; k++ )
118                     {
119                         int num = n + k * 7 + j + 1;
120                         addEdge( i, num, 1 );
121                     }
122                 }
123             }
124         }
125         int tid = n + wmax * 7 + 1;
126         for ( int i = n + 1; i < tid; i++ )
127         {
128             addEdge( i, tid, 1 );
129         }
130         if ( dinic( 0, tid ) == tot )
131         {
132             puts("Yes");
133         }
134         else
135         {
136             puts("No");
137         }
138     }
139     return 0;
140 }

匈牙利解法(些许改变):

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <vector>
  5 using namespace std;
  6 
  7 const int X = 350;
  8 const int Y = 20;
  9 int head[X];
 10 int sz[Y];
 11 bool visit[Y];
 12 vector<int> mark[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 ( mark[v].size() < sz[v] )
 42             {
 43                 mark[v].push_back(u);
 44                 return 1;
 45             }
 46             else
 47             {
 48                 for ( int j = 0; j < mark[v].size(); 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 const int D = 7;
 63 int nn[D];
 64 
 65 int main ()
 66 {
 67     int _case;
 68     scanf("%d", &_case);
 69     while ( _case-- )
 70     {
 71         int n;
 72         scanf("%d", &n);
 73         init();
 74         int tot = 0, wmax = -1, d, w;
 75         for ( int i = 0; i < n; i++ )
 76         {
 77             for ( int j = 0; j < D; j++ )
 78             {
 79                 scanf("%d", nn + j);
 80             }
 81             scanf("%d%d", &d, &w);
 82             sz[i] = d;
 83             tot += d;
 84             wmax = max( wmax, w );
 85             for ( int j = 0; j < D; j++ )
 86             {
 87                 if ( nn[j] == 1 )
 88                 {
 89                     for ( int k = 0; k < w; k++ )
 90                     {
 91                         int num = k * 7 + j;
 92                         addEdge( num, i );
 93                     }
 94                 }
 95             }
 96         }
 97         for ( int i = 0; i < n; i++ )
 98         {
 99             mark[i].clear();
100         }
101         int res = 0;
102         for ( int i = 0; i < 7 * wmax; i++ )
103         {
104             memset( visit, 0, sizeof(visit) );
105             res += dfs(i);
106         }
107         if ( res == tot )
108         {
109             puts("Yes");
110         }
111         else
112         {
113             puts("No");
114         }
115     }
116     return 0;
117 }

 

posted @ 2015-08-22 20:14  hxy_has_been_used  阅读(133)  评论(0编辑  收藏  举报