zoj 2071 Technology Trader 最大权闭合子图

传送门

和上一题一样, 也是一个最大权闭合子图。不过建图好麻烦的感觉  写了好久。

源点和原材料连边, 权值为val。 汇点和产品连边, 权值为val。 产品与和它有关系的材料连边, 权值inf。 最后跑一边网络流, 满流的话是没利润的, 输出结果是利润和-最大流。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define pb(x) push_back(x)
  4 #define ll long long
  5 #define mk(x, y) make_pair(x, y)
  6 #define lson l, m, rt<<1
  7 #define mem(a) memset(a, 0, sizeof(a))
  8 #define rson m+1, r, rt<<1|1
  9 #define mem1(a) memset(a, -1, sizeof(a))
 10 #define mem2(a) memset(a, 0x3f, sizeof(a))
 11 #define rep(i, a, n) for(int i = a; i<n; i++)
 12 #define ull unsigned long long
 13 typedef pair<int, int> pll;
 14 const double PI = acos(-1.0);
 15 const double eps = 1e-8;
 16 const int mod = 1e9+7;
 17 const int inf = 1061109567;
 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 19 const int maxn = 20000;
 20 int head[maxn*4], s, t, num, q[maxn*10], dis[maxn], used[maxn], cnt1, cnt2, ans1[maxn], ans2[maxn];
 21 map <string, int> vis;
 22 struct
 23 {
 24     int val;
 25     string name;
 26 }a[maxn];
 27 struct node
 28 {
 29     int to, nextt, c;
 30 }e[maxn*4];
 31 void init() {
 32     mem1(head);
 33     num = cnt1 = cnt2 = 0;
 34     mem(used);
 35     vis.clear();
 36 }
 37 void add(int u, int v, int c) {
 38     e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++;
 39     e[num].to = u; e[num].nextt = head[v]; e[num].c = 0; head[v] = num++;
 40 }
 41 int bfs() {
 42     int u, v, st = 0, ed = 0;
 43     mem(dis);
 44     dis[s] = 1;
 45     q[ed++] = s;
 46     while(st<ed) {
 47         u = q[st++];
 48         for(int i = head[u]; ~i; i = e[i].nextt) {
 49             v = e[i].to;
 50             if(e[i].c&&!dis[v]) {
 51                 dis[v] = dis[u]+1;
 52                 if(v == t)
 53                     return 1;
 54                 q[ed++] = v;
 55             }
 56         }
 57     }
 58     return 0;
 59 }
 60 int dfs(int u, int limit) {
 61     if(u == t)
 62         return limit;
 63     int cost = 0;
 64     for(int i = head[u]; ~i; i = e[i].nextt) {
 65         int v = e[i].to;
 66         if(e[i].c&&dis[u] == dis[v]-1) {
 67             int tmp = dfs(v, min(limit-cost, e[i].c));
 68             if(tmp>0) {
 69                 e[i].c -= tmp;
 70                 e[i^1].c += tmp;
 71                 cost += tmp;
 72                 if(cost == limit)
 73                     break;
 74             } else {
 75                 dis[v] = -1;
 76             }
 77         }
 78     }
 79     return cost;
 80 }
 81 int dinic() {
 82     int ans = 0;
 83     while(bfs()) {
 84         ans += dfs(s, inf);
 85     }
 86     return ans;
 87 }
 88 void dfs(int u) {
 89     used[u] = 1;
 90     for(int i = head[u]; ~i; i = e[i].nextt) {
 91         int v = e[i].to;
 92         if(e[i].c&&!used[v]) {
 93             dfs(v);
 94         }
 95     }
 96 }
 97 int main()
 98 {
 99     int T, n, q, val, x;
100     cin>>T;
101     while(T--) {
102         cin>>n;
103         init();
104         s = 0;
105         int i, sum = 0;
106         for(i = 1; i<=n; i++) {
107             cin>>a[i].name>>a[i].val;
108             vis[a[i].name] = i;
109             add(s, i, a[i].val);
110         }
111         cin>>q;
112         t = n+q+1;
113         string str;
114         while(q--) {
115             cin>>a[i].name>>a[i].val>>x;
116             sum += a[i].val;
117             add(i, t, a[i].val);
118             while(x--) {
119                 cin>>str;
120                 add(vis[str], i, inf);
121             }
122             i++;
123         }
124         int ans =  sum - dinic();
125         dfs(0);
126         for(int i = head[s]; ~i; i = e[i].nextt) {
127             int v = e[i].to;
128             if(!used[v]) {
129                 ans1[cnt1++] = v;
130             }
131         }
132         for(int i = head[t]; ~i; i = e[i].nextt) {
133             int v = e[i].to;
134             if(!used[v]) {
135                 ans2[cnt2++] = v;
136             }
137         }
138         cout<<ans<<endl;
139         cout<<cnt2<<endl;
140         for(int i = 0; i<cnt2; i++) {
141             cout<<a[ans2[i]].name<<endl;
142         }
143         cout<<cnt1<<endl;
144         for(int i = 0; i<cnt1; i++)
145             cout<<a[ans1[i]].name<<endl;
146     }
147 }
原文地址:https://www.cnblogs.com/yohaha/p/5010916.html