1 #include <stdio.h>
2 #include <
string.h>
3
#define INF 2100000000
4
#define MAXN 103
5
int map[MAXN][MAXN],vis[
1010],v[
1010];
6
int SAP(
int map[][MAXN],
int v_count,
int s,
int t)
//
邻接矩阵,节点总数,始点,汇点
7
{
8
int i;
9
int cur_flow,max_flow,cur,min_label,temp;
//
当前流,最大流,当前节点,最小标号,临时变量
10
char flag;
//
标志当前是否有可行流
11
int cur_arc[MAXN],label[MAXN],neck[MAXN];
//
当前弧,标号,瓶颈边的入点(姑且这么叫吧)
12
int label_count[MAXN],back_up[MAXN],pre[MAXN];
//
标号为i节点的数量,cur_flow的纪录,当前流路径中前驱
13
14
//
初始化
15
memset(label,
0,MAXN*
sizeof(
int));
16 memset(label_count,
0,MAXN*
sizeof(
int));
17
18 memset(cur_arc,
0,MAXN*
sizeof(
int));
19 label_count[
0]=v_count;
//
全部初始化为距离为0
20
21 neck[s]=s;
22 max_flow=
0;
23 cur=s;
24 cur_flow=INF;
25
26
//
循环代替递归
27
while(label[s]<v_count)
28 {
29 back_up[cur]=cur_flow;
30 flag=
0;
31
32
//
选择允许路径(此处还可用邻接表优化)
33
for(i=cur_arc[cur];i<v_count;i++)
//
当前弧优化
34
{
35
if(map[cur][i]!=
0&&label[cur]==label[i]+
1)
//
找到允许路径
36
{
37 flag=
1;
38 cur_arc[cur]=i;
//
更新当前弧
39
if(map[cur][i]<cur_flow)
//
更新当前流
40
{
41 cur_flow=map[cur][i];
42 neck[i]=cur;
//
瓶颈为当前节点
43
}
44
else
45 {
46 neck[i]=neck[cur];
//
瓶颈相对前驱节点不变
47
}
48 pre[i]=cur;
//
记录前驱
49
cur=i;
50
if(i==t)
//
找到可行流
51
{
52 max_flow+=cur_flow;
//
更新最大流
53
54
//
修改残量网络
55
while(cur!=s)
56 {
57
if(map[pre[cur]][cur]!=INF)map[pre[cur]][cur]-=cur_flow;
58 back_up[cur] -= cur_flow;
59
if(map[cur][pre[cur]]!=INF)map[cur][pre[cur]]+=cur_flow;
60 cur=pre[cur];
61 }
62
63
//
优化,瓶颈之后的节点出栈
64
cur=neck[t];
65 cur_flow=back_up[cur];
66 }
67
break;
68 }
69 }
70
if(flag)
continue;
71
72 min_label=v_count-
1;
//
初始化min_label为节点总数-1
73
74
//
找到相邻的标号最小的节点
75
for(i=
0;i<v_count;i++)
76 {
77
if(map[cur][i]!=
0&&label[i]<min_label)
78 {
79 min_label=label[i];
80 temp=i;
81 }
82 }
83 cur_arc[cur]=temp;
//
记录当前弧,下次从提供最小标号的节点开始搜索
84
label_count[label[cur]]--;
//
修改标号纪录
85
if(label_count[label[cur]]==
0)
break;
//
GAP优化
86
label[cur]=min_label+
1;
//
修改当前节点标号
87
label_count[label[cur]]++;
//
修改标号记录
88
if(cur!=s)
89 {
90
//
从栈中弹出一个节点
91
cur=pre[cur];
92 cur_flow=back_up[cur];
93 }
94 }
95
return(max_flow);
96 }
97
int main()
98 {
99
int n,m,i,j,num,temp;
100
101
while(scanf(
"
%d%d
",&m,&n)!=EOF)
102 {
103
for(i=
1;i<=m;i++)
104 scanf(
"
%d
",v+i);
105 memset(vis,
0,
sizeof(vis));
106 memset(map,
0,
sizeof(map));
107
108
for(j=
1;j<=n;j++)
109 {
110 scanf(
"
%d
",&num);
111
while(num--)
112 {
113 scanf(
"
%d
",&temp);
114
if(vis[temp]==
0)
115 map[
0][j]+=v[temp],vis[temp]=j;
116
else
117 map[vis[temp]][j]=INF;
118
//
puts("!");
119
}
120 scanf(
"
%d
",&temp);
121 map[j][n+
1]=temp;
122 }
123 printf(
"
%d\n
",SAP(map,n+
2,
0,n+
1));
124 }
125
return
0;
126 }