Hihocoder #1938 最大权闭合子图模板

这里的讲解很不错,适合作为入坑题:

Hihocoder#1938

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define ms(a,x) memset(a,x,sizeof(a))
using namespace std; int S,T;
const int N=1000,inf=0x3f3f3f3f;
struct node{int y,z,nxt;}e[N*N*2];
int d[N],b[N],q[N],m,n,tot=0,c=1,ans=0,h[N];
void add(int x,int y,int z){
    e[++c]=(node){y,z,h[x]};h[x]=c;
    e[++c]=(node){x,0,h[y]};h[y]=c;
} bool bfs(){
    int f=1,t=0;ms(d,-1);
    q[++t]=S;d[S]=0;
    while(f<=t){
        int x=q[f++];
        for(int i=h[x],y;~i;i=e[i].nxt)
        if(d[y=e[i].y]==-1&&e[i].z)
        d[y]=d[x]+1,q[++t]=y;
    } return (d[T]!=-1);
} int dfs(int x,int f){
    if(x==T) return f;int w,tmp=0;
    for(int i=h[x],y;~i;i=e[i].nxt)
    if(d[y=e[i].y]==d[x]+1&&e[i].z){
        w=dfs(y,min(e[i].z,f-tmp));
        if(!w) d[y]=-1;e[i].z-=w;
        e[i^1].z+=w;tmp+=w;
        if(tmp==f) return f;
    } return tmp;
} void solve(){
    while(bfs()) tot+=dfs(S,inf);
} int main(){ ms(h,-1);int sm=0;
    scanf("%d%d",&n,&m);S=0,T=n+m+1;
    for(int i=1;i<=m;i++)
    scanf("%d",&b[i]),add(i+n,T,b[i]);
    for(int i=1,a,k,t;i<=n;i++){
        scanf("%d%d",&a,&k);
        add(S,i,a);sm+=a;
        while(k--) scanf("%d",&t),add(i,t+n,inf);
    } solve();
    printf("%d
",sm-tot);return 0;
}
原文地址:https://www.cnblogs.com/Alan-Luo/p/10252610.html