bzoj 3438&luogu 1361小Mの作物(最小割)


http://www.elijahqi.win/2018/01/20/bzoj3438/ Description MはMCで2つの巨大な耕地AとB(容量は無限と考えられる)を開き、現在、小Pにはn中作物の種子があり、各作物の種子には1つ(1本の作物を植えることができる)(1...n番号で)があり、現在、i番目の作物をAに植えることでaiの収益を得ることができます.Bで栽培するとbiの収益が得られるし、現在ではいくつかの作物が共同で耕地で追加の収益を得ることができるという不思議な現象がある.小Mは規則を見つけてm種の作物の組み合わせがあり、i番目の組み合わせの作物の共同種はAでc 1 iの追加の収益を得ることができ、共同総Bでc 2 iの追加の収益を得ることができる.Mちゃんはすぐに栽培の最大収益を算出しましたが、彼はあなたを試験したいと思っています.あなたは彼のこの質問に答えることができますか?Inputの第1行は1つの整数nの第2行はn個の整数を含み、aiの第3行はn個の整数を含み、biの第4行は1つの整数mの次のm行を含み、次の第i行に対して:第1の整数kiは、第iの作物の組み合わせにki種の作物があることを示し、次の2つの整数c 1 i,c 2 iは、次のki個の整数は、この組み合わせの作物番号を示す.出力フォーマットOutput
A耕地種1,2,B耕地種3,収益4+2+3+2=11を説明する整数を含む1行のみ.1<=k#include #include #include #include #define inf 0x3f3f3f3f #define N 3300 using namespace std; inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++; } inline int read(){ int x=0;char ch=gc(); while(ch<'0'||ch>'9') ch=gc(); while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc(); return x; } int n,h[N],T,level[N],b[N],num=1,cur[N]; struct node{ int y,z,next; }data[4400000]; inline void insert1(int x,int y,int z){ data[++num].y=y;data[num].z=z;data[num].next=h[x];h[x]=num; data[++num].y=x;data[num].z=0;data[num].next=h[y];h[y]=num; } inline bool bfs(){ queue<int>q;memset(level,0,sizeof(level));level[0]=1;q.push(0); while(!q.empty()){ int x=q.front();q.pop(); for (int i=h[x];i;i=data[i].next){ int y=data[i].y,z=data[i].z; if (level[y]||!z) continue;level[y]=level[x]+1;if (y==T) return 1;q.push(y); } }return 0; } inline int dfs(int x,int s){ if (x==T) return s;int ss=s; for (int &i=cur[x];i;i=data[i].next){ int y=data[i].y,z=data[i].z; if (level[x]+1==level[y]&&z){ int xx=dfs(y,min(z,s));if (!xx) level[y]=0; s-=xx;data[i].z-=xx;data[i^1].z+=xx;if (!s) return ss; } }return ss-s; } int main(){ // freopen("bzoj3438.in","r",stdin); n=read();int sum=0;int x=0; for (int i=1;i<=n;++i) insert1(0,i,x=read()),sum+=x; for (int i=1;i<=n;++i) b[i]=read(),sum+=b[i];int m=read();T=n;T+=m<<1;++T; for (int i=1;i<=n;++i) insert1(i,T,b[i]); for (int i=1;i<=m;++i){ int k=read();insert1(0,n+i,x=read());sum+=x;insert1(n+m+i,T,x=read());sum+=x; for (int j=1;j<=k;++j){ insert1(i+n,x=read(),inf);insert1(x,i+n+m,inf); } }int ans=0;while(bfs()) memcpy(cur,h,sizeof(h)),ans+=dfs(0,inf); printf("%d",sum-ans); return 0; }