大水题,我自己瞎做就做出来了,没啥说的,zz建图,就是板子。
题干:
题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化。由于很多来住店的旅客有自己喜好的房间色调、阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜。 有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜。但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜)。 这里要怎么分配,能使最多顾客满意呢? 输入输出格式 输入格式: 第一行给出三个正整数表示n,p,q(<=100)。 之后n行,每行p个数包含0或1,第i个数表示喜不喜欢第i个房间(1表示喜欢,0表示不喜欢)。 之后n行,每行q个数,表示喜不喜欢第i道菜。 输出格式: 最大的顾客满意数。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 1e3 + 5; struct node { int l,r,nxt,w,oth; }a[N * 10]; int len = 0,lst[N]; void add(int x,int y,int w) { // cout<<x<<" "<<y<<" "<<w<<endl; int k1,k2; a[++len].l = x; a[len].r = y; a[len].w = w; a[len].nxt = lst[x]; lst[x] = len; k1 = len; a[++len].l = y; a[len].r = x; a[len].w = 0; a[len].nxt = lst[y]; lst[y] = len; k2 = len; a[k1].oth = k2; a[k2].oth = k1; } int n,p,q; int h[N],ed = 0; bool bfs() { clean(h); h[0] = 1; queue <int> q; q.push(0); while(!q.empty()) { int x = q.front(); q.pop(); for(int k = lst[x];k != -1;k = a[k].nxt) { int y = a[k].r; if(a[k].w > 0 && h[y] == 0) { h[y] = h[x] + 1; q.push(y); } } } if(h[ed] > 0) return true; else return false; } int find(int x,int f) { if(x == ed) { return f; } int s = 0,t; for(int k = lst[x];k != -1;k = a[k].nxt) { int y = a[k].r; if(s < f && h[y] == h[x] + 1 && a[k].w > 0) { t = find(y,min(a[k].w,f - s)); s += t; a[k].w -= t; a[a[k].oth].w += t; } } if(s == 0) h[x] = 0; return s; } int main() { read(n);read(p);read(q); memset(lst,-1,sizeof(lst)); duke(i,1,n) add(0,i,1); duke(i,1,n) { duke(j,1,p) { int x; read(x); if(x == 1) { add(j,p + i,1); } } } duke(i,1,n) { add(p + i,p + n + i,1); } duke(i,1,n) { duke(j,1,p) { int x; read(x); if(x == 1) { add(p + n + i,p + 2 * n + j,1); } } } ed = 2 * p + 2 * n + 1; duke(i,1,p) { add(p + 2 * n + i,ed,1); } int s = 0,t,l; while(bfs() == true) { s += find(0,INF); } printf("%d\n",s); return 0; }