Human life FZU

Xzz is playing a MMORPG "human life".

In this game, there are N different skills. Some skills may base on another skill.

Learning skill will cost Xzz some money.

And there are M different jobs. If Xzz's skills satisfy the job's requirement, then Xzz can get this job, and get some money.

But some jobs are conflict, some Xzz can't get the job at same time.

There are K pairs of jobs are conflict.

Now Xzz want to know the money he can get at the most,can you help him.

Input

First line of the input file contains an integer T(0 < T ≤ 10) that indicates how many cases of inputs are there.

The description of each case is given below:

The first line of each input case contains number N, M, K. N <= 100, M <= 50, K <= 5.

Then follow N lines. In ith line the first two number ? ,? , means learning skill i const vi , skill i base on another ni skills. The last ni number aij means before learning skill i Xzz need to learn skill aij. 0 ≤ vi ≤ 1000, 0 ≤ ni ≤ N

Then follow M lines. In ith line the first two number wi, mi , means job i earn wi, jobs i base on mi skills. The last mi number bij means get job i need to learn skill bij. 0 ≤ wi ≤ 1000, 0 ≤ mi ≤ M

Then follow K lines. In ith line the first two number ci, di, means job ci conflict with job di.

Output

The description of output for each test case is given below:

The first line of the output for each test case contains number answer, the maximum money Xzz can get.

Sample Input

2
5 2 0
1 0
1 1 1
1 0
1 0
1 1 4
10 2 2 3
8 2 3 5
5 2 1
1 0
1 1 1
1 0
1 0
1 1 4
10 2 2 3
8 2 3 5
1 2

Sample Output

13
7

今天组队训练,这个我负责的图论部分没有写出来 难受啊
今天想拿网络流 流过去结果建图不知道该怎么建图 流也流不对
结束后才知道这就是最大权闭合子图的板子题目
唉 图论的基本套路我都还没有掌握 难受啊

今天然后晚上认真的学习了最大权闭合子图

点击这里学习最大权闭合子图 博主很良心讲的非常好

然后下面这一题就稍微的改动了一下
一开始我还在想k如何处理 ,后来学长告诉我k最大为5 直接枚举所有情况就好了

然后就是基本的建图操作


  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <set>
  7 #include <iostream>
  8 #include <map>
  9 #include <stack>
 10 #include <string>
 11 using namespace std;
 12 #define pi acos(-1.0)
 13 #define eps 1e-6
 14 #define fi first
 15 #define se second
 16 #define lson l,m,rt<<1
 17 #define rson m+1,r,rt<<1|1
 18 #define bug      printf("******")
 19 #define mem(a,b) memset(a,b,sizeof(a))
 20 #define fuck(x)  cout<<"["<<x<<"]"<<endl
 21 #define f(a)     a*a
 22 #define san(n,m) scanf("%d%d",&n,&m)
 23 #define FIN freopen("in.txt","r",stdin)
 24 #define lowbit(x) x&-x
 25 #pragma comment (linker,"/STACK:102400000,102400000")
 26 using namespace std;
 27 const int maxn = 100004;
 28 typedef long long LL;
 29 const int MX = 450;
 30 const int MXE = 4 * MX * MX;
 31 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
 32 const int INF = 0x3f3f3f;
 33 struct MaxFlow {
 34     struct Edge {
 35         int v, nxt;
 36         LL w;
 37     } E[MXE];
 38     int tot, num, s, t;
 39     int head[MX];
 40     void init() {
 41         memset (head, -1, sizeof (head) );
 42         tot = 0;
 43     }
 44     void add (int u, int v, LL w) {
 45         E[tot] = (Edge) {
 46             v, head[u], w
 47         };
 48         head[u] = tot++;
 49         E[tot] = (Edge) {
 50             u, head[v], 0
 51         };
 52         head[v] = tot++;
 53     }
 54     int  d[MX], vis[MX], gap[MX];
 55     void bfs() {
 56         memset (d, 0, sizeof (d) );
 57         memset (gap, 0, sizeof (gap) );
 58         memset (vis, 0, sizeof (vis) );
 59         queue<int>q;
 60         q.push (t);
 61         vis[t] = 1;
 62         while (!q.empty() ) {
 63             int u = q.front();
 64             q.pop();
 65             for (int i = head[u]; ~i; i = E[i].nxt) {
 66                 int v = E[i].v;
 67                 if (!vis[v]) {
 68                     d[v] = d[u] + 1;
 69                     gap[d[v]]++;
 70                     q.push (v);
 71                     vis[v] = 1;
 72                 }
 73             }
 74         }
 75     }
 76     int last[MX];
 77     LL dfs (int u, LL f) {
 78         if (u == t) return f;
 79         LL sap = 0;
 80         for (int i = last[u]; ~i; i = E[i].nxt) {
 81             int v = E[i].v;
 82             if (E[i].w > 0 && d[u] == d[v] + 1) {
 83                 last[u] = i;
 84                 LL tmp = dfs (v, min (f - sap, E[i].w) );
 85                 E[i].w -= tmp;
 86                 E[i ^ 1].w += tmp;
 87                 sap += tmp;
 88                 if (sap == f) return sap;
 89             }
 90         }
 91         if (d[s] >= num) return sap;
 92         if (! (--gap[d[u]]) ) d[s] = num;
 93         ++gap[++d[u]];
 94         last[u] = head[u];
 95         return sap;
 96     }
 97     LL solve (int st, int ed, int n) {
 98         LL flow = 0;
 99         num = n;
100         s = st;
101         t = ed;
102         bfs();
103         memcpy (last, head, sizeof (head) );
104         while (d[s] < num) flow += dfs (s, INFLL);
105         return flow;
106     }
107 } F;
108 int t, n, m, k, vis[505];
109 struct node {
110     int val, n;
111     int num[55];
112 } a[505], b[505];
113 struct node1 {
114     int x, y;
115 } p[maxn];
116 int main() {
117     scanf("%d", &t);
118     while(t--) {
119         scanf("%d%d%d", &n, &m, &k);
120         for (int i = 1 ; i <= n ; i++) {
121             scanf("%d%d", &a[i].val, &a[i].n);
122             for (int j = 0 ; j < a[i].n ; j++) scanf("%d", &a[i].num[j]);
123         }
124         for  (int i = 1 ; i <= m ; i++) {
125             scanf("%d%d", &b[i].val, &b[i].n);
126             for (int j = 0 ; j < b[i].n ; j++) scanf("%d", &b[i].num[j]);
127         }
128         for (int i = 0 ; i < k ; i++) scanf("%d%d", &p[i].x, &p[i].y);
129         int st = 0, ed = n + m + 1;
130         LL ans = 0;
131         for (int i = 0 ; i < (1 << k) ; i++) {
132             LL sum = 0;
133             F.init();
134             memset(vis, 0, sizeof(vis));
135             for (int j = 0 ; j < k ; j++) {
136                 if (vis[p[j].x] && vis[p[j].y] ) continue;
137                 if ((i >> j) & 1) vis[p[j].y] = 1;
138                 else vis[p[j].x] = 1;
139             }
140             for (int j = 1 ; j <= m ; j++) {
141                 if (vis[j]) continue;
142                 sum += 1LL * b[j].val;
143                 F.add(st, j, b[j].val);
144                 for (int p = 0 ; p < b[j].n ; p++) F.add(j, m + b[j].num[p], INF);
145             }
146             for (int j = 1 ; j <= n ; j++) {
147                 F.add(m + j, ed, a[j].val);
148                 for (int p = 0 ; p < a[j].n ; p++) F.add(m + j, m + a[j].num[p], INF);
149             }
150             LL temp = F.solve(st, ed, n + m + 2);
151             ans = max(ans, sum - temp);
152         }
153         printf("%lld
", ans);
154     }
155     return 0;
156 }
原文地址:https://www.cnblogs.com/qldabiaoge/p/9539287.html