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 直接枚举所有情况就好了 然后就是基本的建图操作
 #include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <iostream>
#include <map>
#include <stack>
#include <string>
using namespace std;
#define pi acos(-1.0)
#define eps 1e-6
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define bug printf("******")
#define mem(a,b) memset(a,b,sizeof(a))
#define fuck(x) cout<<"["<<x<<"]"<<endl
#define f(a) a*a
#define san(n,m) scanf("%d%d",&n,&m)
#define FIN freopen("in.txt","r",stdin)
#define lowbit(x) x&-x
#pragma comment (linker,"/STACK:102400000,102400000")
using namespace std;
const int maxn = ;
typedef long long LL;
const int MX = ;
const int MXE = * MX * MX;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f;
struct MaxFlow {
struct Edge {
int v, nxt;
LL w;
} E[MXE];
int tot, num, s, t;
int head[MX];
void init() {
memset (head, -, sizeof (head) );
tot = ;
}
void add (int u, int v, LL w) {
E[tot] = (Edge) {
v, head[u], w
};
head[u] = tot++;
E[tot] = (Edge) {
u, head[v],
};
head[v] = tot++;
}
int d[MX], vis[MX], gap[MX];
void bfs() {
memset (d, , sizeof (d) );
memset (gap, , sizeof (gap) );
memset (vis, , sizeof (vis) );
queue<int>q;
q.push (t);
vis[t] = ;
while (!q.empty() ) {
int u = q.front();
q.pop();
for (int i = head[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if (!vis[v]) {
d[v] = d[u] + ;
gap[d[v]]++;
q.push (v);
vis[v] = ;
}
}
}
}
int last[MX];
LL dfs (int u, LL f) {
if (u == t) return f;
LL sap = ;
for (int i = last[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if (E[i].w > && d[u] == d[v] + ) {
last[u] = i;
LL tmp = dfs (v, min (f - sap, E[i].w) );
E[i].w -= tmp;
E[i ^ ].w += tmp;
sap += tmp;
if (sap == f) return sap;
}
}
if (d[s] >= num) return sap;
if (! (--gap[d[u]]) ) d[s] = num;
++gap[++d[u]];
last[u] = head[u];
return sap;
}
LL solve (int st, int ed, int n) {
LL flow = ;
num = n;
s = st;
t = ed;
bfs();
memcpy (last, head, sizeof (head) );
while (d[s] < num) flow += dfs (s, INFLL);
return flow;
}
} F;
int t, n, m, k, vis[];
struct node {
int val, n;
int num[];
} a[], b[];
struct node1 {
int x, y;
} p[maxn];
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i <= n ; i++) {
scanf("%d%d", &a[i].val, &a[i].n);
for (int j = ; j < a[i].n ; j++) scanf("%d", &a[i].num[j]);
}
for (int i = ; i <= m ; i++) {
scanf("%d%d", &b[i].val, &b[i].n);
for (int j = ; j < b[i].n ; j++) scanf("%d", &b[i].num[j]);
}
for (int i = ; i < k ; i++) scanf("%d%d", &p[i].x, &p[i].y);
int st = , ed = n + m + ;
LL ans = ;
for (int i = ; i < ( << k) ; i++) {
LL sum = ;
F.init();
memset(vis, , sizeof(vis));
for (int j = ; j < k ; j++) {
if (vis[p[j].x] && vis[p[j].y] ) continue;
if ((i >> j) & ) vis[p[j].y] = ;
else vis[p[j].x] = ;
}
for (int j = ; j <= m ; j++) {
if (vis[j]) continue;
sum += 1LL * b[j].val;
F.add(st, j, b[j].val);
for (int p = ; p < b[j].n ; p++) F.add(j, m + b[j].num[p], INF);
}
for (int j = ; j <= n ; j++) {
F.add(m + j, ed, a[j].val);
for (int p = ; p < a[j].n ; p++) F.add(m + j, m + a[j].num[p], INF);
}
LL temp = F.solve(st, ed, n + m + );
ans = max(ans, sum - temp);
}
printf("%lld\n", ans);
}
return ;
}

最新文章

  1. UVa 221城市正视图(离散化)
  2. HDP 2.3 Notes
  3. Select for update/lock in share mode 对事务并发性影响
  4. MySQL调优参数
  5. 设置完在Canvas的位置后,控件HitTest不响应的问题
  6. Java学习笔记之:Java简介
  7. HDOJ(HDU) 2138 How many prime numbers(素数-快速筛选没用上、)
  8. 使用Python,字标注及最大熵法进行中文分词
  9. SQLServer 2008 R2 发布订阅配置指南
  10. DLP显示单元(威创)
  11. 使用gulp构建自动化工作流
  12. WebService详解(二)
  13. 一张图读懂PBN飞越转弯衔接DF航段计算
  14. 萌新 学习 vuex
  15. BZOJ4756: [Usaco2017 Jan]Promotion Counting(线段树合并)
  16. 1.横向滚动条,要设置两个div包裹. 2. 点击切换视频或者图片. overflow . overflow-x
  17. 使用U盘安装Ubuntu系统
  18. Java反射获取对象VO的属性值(通过Getter方法)
  19. SQL学习之MYSQL的常用命令和增删改查语句和数据类型
  20. CDN公共库、前端开发常用插件一览表(VendorPluginLib)

热门文章

  1. @meida 媒体查询
  2. Java VisualVM使用
  3. 珍珠 Median Weight Bead 977
  4. Multi-task Correlation Particle Filter for Robust Object Tracking--论文随笔
  5. 线性代数之——微分方程和 exp(At)
  6. 统计学习三:2.K近邻法代码实现(以最近邻法为例)
  7. opencv-学习笔记(1)常用函数和方法。
  8. 安装HIVE
  9. RedHat/CentOS利用iso镜像做本地yum源
  10. 第十九次ScrumMeeting会议