题意分析
当时感觉就是网络流,然后学了如何建图,但是脑残+手残正反边都给建成INF了,凉凉。
代码总览
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int nmax = 100000;
const int INF = 0x3f3f3f3f;
typedef struct {
int to,nxt;
ll w;
}Edge;
Edge e[nmax<<1];
int head[nmax<<1];
int cur[nmax];
int dep[nmax];
ll val[nmax];
ll cost[nmax];
int tot = 0, tt, n, m, n1, n2, S ,T;
ll ans = 0;
void add(int u, int v, ll w){
e[tot].to = v;
e[tot].nxt = head[u];
e[tot].w = w;
head[u] = tot++;
}
bool bfs(){
memset(dep,-1,sizeof dep);
dep[S] = 0; queue<int> q; q.push(S);
while(!q.empty()){
int u = q.front(); q.pop();
for(int i = head[u]; i!= -1; i = e[i].nxt){
int v = e[i].to;
if(dep[v] == -1 && e[i].w){
dep[v] = dep[u] +1;
q.push(v);
}
}
}
return dep[T] != -1;
}
ll dfs(int now, ll flow){
if(now == T || flow == 0) return flow;
ll f = 0;
for(int & i = cur[now];i !=-1 ; i = e[i].nxt){
int v = e[i].to;
if(dep[v] == dep[now] + 1 && e[i].w){
ll temp = dfs(v, min(e[i].w,flow));
if(temp){
e[i].w -= temp;
e[i^1].w += temp;
f += temp;
flow -= temp;
if(flow == 0) break;
}
}
}
return f;
}
void dinic(){
while(bfs()){
for(int i = 0;i<=T;++i) cur[i] = head[i];
while(ll tt = dfs(S,INF)) ans -= tt;
}
}
int main(){
scanf("%d",&tt);
while(tt--){
scanf("%d %d",&n,&m);
S = n + m + 1; T = S + 1, ans = 0; tot = 0;
memset(head,-1,sizeof head);
memset(e,0,sizeof e);
memset(val,0,sizeof val);
memset(cost,0,sizeof cost);
for(int i = 1;i<=n;++i) {
scanf("%lld",&val[i]);
add(S,i,val[i]);
add(i,S,0);
ans += val[i];
// cout<<S<<" "<< i << val[i] << endl;
}
for(int i = 1;i<=m;++i){
scanf("%lld",&cost[i]);
add(i+n,T,cost[i]);
add(T,i+n,0);
// cout<<i+n<<" "<< T << cost[i] << endl;
}
int temp = 0;
for(int i = 1;i<=n;++i){
scanf("%d %d",&n1,&n2);
for(int j = 1;j<=n1;++j) {
scanf("%d",&temp);
add(i,temp+n,INF);
add(temp+n,i,0);
// cout<<i <<" "<< temp+n << " INF"<<endl;
}
for(int j = 1;j<=n2;++j) {
scanf("%d",&temp);
add(i,temp,INF);
add(temp,i,0);
// cout<<i<<" "<< temp << " INF"<< endl;
}
}
dinic();
printf("%lld\n",ans);
}
return 0;
}