zoukankan      html  css  js  c++  java
  • p2805 [NOI2009]植物大战僵尸

    传送门

    分析

    我们知道一个点可以保护他射程的那几个点和他左边的那个点

    我们又知道如果保护关系成环则环中的点以及这些点左面的点均是无敌的

    所以我们按保护关系连边,然后跑tarjan

    然后只要找出点数大于1的联通块中的点即可

    之后问题就转换为了求无敌点之外的点所构成图的最大权闭合子图

    注意此处是正权点连T,负权点连S,因为此处闭合图是值选一个点的同时必须选所有能到达它的点

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define id(x,y) (x-1)*m+y
    const int inf = 1e9+7;
    int n,m,s[80000],is[80000],Ans,S,T;
    vector<int>p[80000];
    vector<int>v[80000];
    int dfn[80000],low[80000],ist[80000],cnt,sum,belong[80000],tot[80000];
    stack<int>a;
    inline void tarjan(int x){
        low[x]=dfn[x]=++cnt;
        a.push(x);
        ist[x]=1;
        for(int i=0;i<v[x].size();i++){
          if(!dfn[v[x][i]]){
              tarjan(v[x][i]);
              low[x]=min(low[x],low[v[x][i]]);
          }else if(ist[v[x][i]]){
              low[x]=min(low[x],dfn[v[x][i]]);
          }
        }
        if(low[x]==dfn[x]){
          sum++;
          while(1){
              int u=a.top();
              a.pop();
              ist[u]=0;
              belong[u]=sum;
              tot[sum]++;
              if(u==x)break;
          }
        }
    }
    int head[2000100],w[2000100],nxt[2000100],to[2000100],ano[2000100],res;
    int level[80000],cur[2000100];
    inline void add(int x,int y,int z){
        nxt[++res]=head[x];head[x]=res;to[res]=y;w[res]=z;
        nxt[++res]=head[y];head[y]=res;to[res]=x;w[res]=0;
        ano[res]=res-1;ano[res-1]=res;
    }
    inline bool bfs(){
        memset(level,-1,sizeof(level));
        queue<int>q;
        level[S]=0;
        q.push(S);
        while(!q.empty()){
          int x=q.front();
          q.pop();
          for(int i=head[x];i;i=nxt[i])
            if(level[to[i]]==-1&&w[i]){
              level[to[i]]=level[x]+1;
              if(to[i]==T)return 1;
              q.push(to[i]);
            }
        }
        return 0;
    }
    inline int dfs(int x,int flow){
        if(x==T||!flow)return flow;
        int res=0;
        cur[x]=head[x];
        for(int i=cur[x];i;i=nxt[i]){
          cur[x]=i;
          if(level[to[i]]==level[x]+1&&w[i]){
              int f=dfs(to[i],min(flow-res,w[i]));
              w[i]-=f;
              w[ano[i]]+=f;
              res+=f;
          }
        }
        if(!res)level[x]=-1;
        return res;
    }
    int main(){
        int i,j,k,x;
        scanf("%d%d",&n,&m);
        S=n*m+10,T=S+1;
        for(i=1;i<=n;i++)
          for(j=1;j<=m;j++){
            scanf("%d",&s[id(i,j)]);
              scanf("%d",&x);
              for(k=1;k<=x;k++){
              int y,z;
              scanf("%d%d",&y,&z);
              p[id(i,j)].push_back(id(y+1,z+1)); 
            } 
          }
        for(i=1;i<=n;i++)
          for(j=1;j<=m;j++){
              if(j!=1)v[id(i,j)].push_back(id(i,j-1));
              for(k=0;k<p[id(i,j)].size();k++)
                v[id(i,j)].push_back(p[id(i,j)][k]);
          }
        for(i=1;i<=n*m;i++)
          if(!dfn[i])tarjan(i);
        for(i=1;i<=n;i++)
          for(j=m;j>0;j--)
            if(tot[belong[id(i,j)]]!=1){
              for(k=j;k>0;k--){
                is[id(i,k)]=1;
              }
              break;
            }
        for(i=1;i<=n;i++)
          for(j=1;j<=m;j++){
              if(is[id(i,j)])continue;
              if(j!=1&&!is[id(i,j-1)])add(id(i,j),id(i,j-1),inf);
              for(k=0;k<p[id(i,j)].size();k++)
                if(!is[p[id(i,j)][k]])add(id(i,j),p[id(i,j)][k],inf);
              if(s[id(i,j)]>0){
                Ans+=s[id(i,j)];
                add(id(i,j),T,s[id(i,j)]);
              }else {
                add(S,id(i,j),-s[id(i,j)]);
              }
          }
        while(bfs())while(int a=dfs(S,inf))Ans-=a;
        cout<<Ans;
        return 0;
    }
  • 相关阅读:
    JSON 序列化类 南京酷得软件
    哈哈哈哈哈哈 找回记忆
    Presto
    (转)在Total Commander下使用SVN
    在ubuntu12.04,64位中安装lnmp一键包mysql的问题
    阿里云服务器上搭建php环境+redis
    在ubuntu12.04,64位中安装nginx+php+redis+mysql
    Redis篇:单线程I/O模型
    工具篇:apachehttpClient 和 jdk11HttpClient的使用
    技能篇:关于缓存数据的一致性探讨
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10356810.html
Copyright © 2011-2022 走看看