码迷,mamicode.com
首页 > 其他好文 > 详细

[NOI2009]植物大战僵尸

时间:2018-03-01 21:37:09      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:show   col   log   define   最大   eof   nbsp   targe   har   

题链

SOL:最大权闭合子图,记得判环,边拓扑时要反向存,正反的答案不一样。

我们考虑一个环,其每一个点都向中点连边,正向的话中点时判环中的,反向就判在环外了。

#include<bits/stdc++.h>
using namespace std;
template <class T>
#define gc getchar
#define sight(c) (‘0‘<=c&&c<=‘9‘)
inline void read(T &x){
    static int b; static char c;
    for (b=1,c=gc();!sight(c);c=gc()) if (c==-) b=-1;
    for (x=0;sight(c);c=gc()) x=x*10+c-48;
    x*=b;
}
struct maxflow{
     #define N 100007
     #define M 1000007
     #define inf (1<<29)
     #define eho(x) for (int i=head[x];i;i=net[i])
     #define Eho(x) for (int &i=hea[x];i;i=net[i])
     int n,s,t,head[N],hea[N],net[M],fall[M],tot,gap[N],d[N],cost[M],p[N],be,ed,x,ret;
     maxflow() {tot=1;memset(head,0,sizeof head);}
     inline void clear() {
         tot=1; memset(head,0,sizeof head);}
     inline void add(int x,int y,int z){
         fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=z;
     }
     inline void adds(int x,int y,int z){
         add(x,y,z); add(y,x,0);
     }
     void init() {
         memset(gap,0,sizeof gap); memset(d,0,sizeof d);
         ++gap[d[t]=1];
         memcpy(hea,head,sizeof hea);
         p[be=ed=1]=t; 
         while (be<=ed) {
             x=p[be++];
             eho(x) if (!d[fall[i]]) ++gap[d[fall[i]]=d[x]+1],p[++ed]=fall[i];
         }
     }
     int get(int x,int fl){
         if (x==t) return fl; if (!fl) return 0;
         int flow=0,tmp;
         Eho(x) if (d[x]==d[fall[i]]+1&&(tmp=get(fall[i],min(fl,cost[i])))) {
             flow+=tmp; fl-=tmp; cost[i]-=tmp; cost[i^1]+=tmp;
             if (!fl) return flow;
        } 
        if (!(--gap[d[x]])) d[s]=n+1;
        ++gap[++d[x]]; hea[x]=head[x];
        return flow;
     }
     int isap(int x,int y,int siz){
         s=x; t=y; n=siz;
         init();
         ret=get(s,inf);
         while (d[s]<=n) ret+=get(s,inf);
         return ret;
     }
}G;
#define r(x,y) (x*m+y+1)
int n,m,tot,head[N],fall[M],net[M],q[N],be,ed,mp[N],p,x,y,in[N],v[N],sum;
inline void add(int x,int y){fall[++tot]=y; net[tot]=head[x]; head[x]=tot; }
int main () {
//    freopen("a.in","r",stdin);
    read(n); read(m);
    for(int i=1;i<=n*m;i++) {
        read(mp[i]); read(p);
        while (p--) {
            read(x); read(y);
//            add(r(x,y),i); in[i]++;
            add(i,r(x,y)); in[r(x,y)]++;
        }
        if (i%m) add(i+1,i),in[i]++;
//        add(i,i+1),in[i+1]++;
    }
    for (int i=n*m;i;i--) if (!in[i]) q[ed++]=i;
    while (be<ed) {
        x=q[be++]; v[x]=1;
        eho(x) if (!(--in[fall[i]])) q[ed++]=fall[i];
    }
    for (int x=1;x<=n*m;x++) if (v[x]){
        if (mp[x]>0) G.adds(0,x,mp[x]),sum+=mp[x]; else G.adds(x,n*m+1,-mp[x]);
        eho(x) if(v[fall[i]]) G.adds(fall[i],x,inf);
    } 
    printf("%d",sum-G.isap(0,n*m+1,n*m+2));
}

 

[NOI2009]植物大战僵尸

标签:show   col   log   define   最大   eof   nbsp   targe   har   

原文地址:https://www.cnblogs.com/rrsb/p/8490411.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!