网络流:
#pragma GCC optimize("O2") #include<bits/stdc++.h> #define eho(x) for(int& i=hed[x];~i;i=net[i]) #define Eho(x) for(int i=head[x];~i;i=net[i]) #define sight(c) (‘0‘<=c&&c<=‘9‘) #define INF (1<<27) inline void read(int &x){ static char c;static int b; for (b=1,c=getchar();!sight(c);c=getchar())if(c==‘-‘)b=-1; for (x=0;sight(c);c=getchar())x=x*10+c-48; x*=b; } using namespace std; #define N 707 #define M 927007 int n,a[N][N],ni[N],t,x,ans; bool usd[N]; struct G{ int head[N],net[M],fall[M],cost[M],s,t,tot,d[N],hed[N]; bool in[N]; queue<int> Q; G() { memset(head,-1,sizeof head);tot=-1;} inline void add(int x,int y,int c){ fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=c; } inline void adds(int x,int y,int c){ add(x,y,c); add(y,x,0);} inline bool spfa(){ memset(d,127,sizeof d); int x; d[s]=1; Q.push(s); in[s]=1; while (!Q.empty()) { x=Q.front(); Q.pop(); Eho(x) if (cost[i]&&d[fall[i]]>d[x]+1) { d[fall[i]]=d[x]+1; if (!in[fall[i]]) {in[fall[i]]=1,Q.push(fall[i]);} } in[x]=0; } return d[t]<INF; } inline int dfs(int x,int F){ if (x==t|| !F) return F; int flow=0,r; eho(x) if (d[x]+1==d[fall[i]]&&((r=dfs(fall[i],min(F,cost[i])))>0)) { cost[i]-=r; cost[i^1]+=r; F-=r; flow+=r; if (!F) break;} return flow; } int dinic(int A,int B){ s=A; t=B; int flow=0; while (spfa()) { memcpy(hed,head,sizeof head); flow+=dfs(s,INF); } return flow; } }G; void write(int x) {if (x<10) {putchar(‘0‘+x);return;} write(x/10); putchar(‘0‘+x%10);} inline void writeln(int x) {if (x<0) putchar(‘-‘),x*=-1; write(x); putchar(‘\n‘);} bool find(int x) { for (int i=1;i<=n;i++) if (a[x][i]&&!usd[i]) { usd[i]=1; if (!ni[i]||find(ni[i])) return ni[i]=x,1; } return 0; } int main () { //freopen("c.in","r",stdin); read(n); for (int i=1;i<=n;i++) { read(t); while (t--) read(x),a[i][x]=1,G.adds(i,n+x,INF); } for (int i=1;i<=n;i++) memset(usd,0,sizeof usd), find(i); for (int i=1;i<=n;i++) { read(x); if (x<0) ans+=x,G.adds(0,i,-x); else G.adds(i,2*n+3,x); G.adds(n+i,ni[i],INF); } writeln(ans+G.dinic(0,2*n+3)); return 0; }