uva

来源:互联网 发布:网络铺设 编辑:程序博客网 时间:2024/04/28 23:50

题意:m个产品,n个插头,k种转化器。无限多个,求有几个产品不能配上插头

思路:

建图从原点到产品,产品到对应的插头,如果这种插头有转化器,则插头连向插头,个数为无穷

产品1-m,插头m+1-m+n,这里要特别注意,因为有除了n种以外的插头需要特别记录下来,最终只能转化为n个里面的一种才能用

代码:

#include<cstdio>#include<iostream>#include<queue>#include<cstring>#include<map>using namespace std;const int INF = 0x3c3c3c3c;int n, m, k;const int maxn = 310;map<string, int> rs, dv;int p[maxn];int c[maxn][maxn];int f[maxn][maxn];int a[maxn];void ek(int ed) {memset(f, 0, sizeof(f));queue<int> q;int ans = 0;while(1) {memset(p, 0, sizeof(p));memset(a, 0, sizeof(a));a[0] = INF;q.push(0);while(!q.empty()) {int u = q.front();q.pop();for(int i=0; i<=ed; i++) {if(c[u][i]>f[u][i] && !a[i]) {a[i] = min(a[u], c[u][i]-f[u][i]);q.push(i);p[i] = u;}}}if(a[ed] == 0) break;for(int i=ed; i; i=p[i]) {f[p[i]][i] += a[ed];f[i][p[i]] -= a[ed];}ans += a[ed];}printf("%d\n", m-ans);}string str;int main() {int kase;string str;int adt = 0;int rid, did;scanf("%d", &kase);while(kase--) {adt = 0;memset(c, 0, sizeof(c));scanf("%d", &n);rs.clear();dv.clear();for(int i=1; i<=n; i++) {cin>>str;rs[str] = i;}scanf("%d", &m);for(int i=1; i<=m; i++) {cin>>str;if(dv[str] == 0) {dv[str] = i;}did = dv[str];c[0][did] += 1;cin>>str;if(rs[str] == 0) {adt++;rs[str] = n+adt;}rid = rs[str];c[did][rid+m] += 1;}    for(int i=m+1; i<=m+n; i++) c[i][m+n+adt+1] += 1;scanf("%d", &k);for(int i=0; i<k; i++) {cin>>str;rid = rs[str];cin>>str;c[rid+m][rs[str]+m] = INF;}ek(m+n+adt+1);if(kase) printf("\n");}return 0;}


0 0
原创粉丝点击