• [NOI2009] 植物大战僵尸


    题意:

    给定一张$n imes m$的网格图,每个点有个植物,价值$Score$,能控制点集$S$。

    现在有一些僵尸攻击这些植物,每个僵尸可以任选一行,然后从第$m+1$列一直往左走,消灭遇到的所有植物。

    如果一个僵尸走到某个格子,它被一个没被消灭的植物控制着,则这个僵尸会被消灭。

    你可以派出任意个僵尸,求攻击植物所能获得的最大价值。

    $n,mleq 30,-10^4 leq Scoreleq 10^4$。

    题解:

    互相有控制关系的网络流问题基本就是最大权闭合子图,于是直接无脑建模就做完了。

    注意到如果两个点位于同一个强联通分量,那么它们永远没法产生贡献。

    朴素的做法是用$tarjan$判掉,但其实也可以拓扑排序,最后没在队列里的点直接删掉即可。

    复杂度$O(能过)$。

    套路:

    • 互相有控制关系的网络流问题$ ightarrow$最大权闭合子图。
    • 判强联通分量$ ightarrow$Tarjan或拓扑排序。

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<stack>
    #define maxn 1000005
    #define maxm 500005
    #define inf 0x7fffffff
    #define ll long long
    
    using namespace std;
    int N,M,A[maxn],hd[maxn],to[maxn<<1];
    int T,S,cnt=1,nxt[maxn<<1],fl[maxn<<1];
    int dfn[maxn],low[maxn],dis[maxn],num; 
    bool ins[maxn],vis[maxn]; 
    stack<int> s;
    
    inline int read(){
        int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline int calc(int x,int y){return x*M+y+1;}
    inline void addedge(int u,int v,int w){
        to[++cnt]=v,fl[cnt]=w,nxt[cnt]=hd[u],hd[u]=cnt;
        to[++cnt]=u,fl[cnt]=0,nxt[cnt]=hd[v],hd[v]=cnt;
    }
    
    inline bool spfa(){
        memset(dis,-1,sizeof(dis));
        queue<int> q;
        q.push(S),dis[S]=0;
        while(!q.empty()){
            int u=q.front(); q.pop();
            if(u==T) break;
            for(int i=hd[u];i;i=nxt[i]){
                int v=to[i];
                if(dis[v]==-1 && fl[i]>0)
                    dis[v]=dis[u]+1,q.push(v);
            }
        }
        return dis[T]!=-1;
    }
    inline int dfs(int u,int flow){
        if(u==T) return flow;
        int sum=0;
        for(int i=hd[u];i;i=nxt[i]){
            int v=to[i];
            if(dis[v]==dis[u]+1 && fl[i]>0){
                int f=dfs(v,min(flow,fl[i]));
                fl[i]-=f,fl[i^1]+=f,sum+=f,flow-=f;
                if(!flow) break;
            } 
        } 
        if(sum==0) dis[u]=-1;
        return sum;
    }
    inline int Dinic(){
        int ans=0;
        while(spfa()) ans+=dfs(S,inf);
        return ans;
    }
    
    inline void tarjan(int u){
        dfn[u]=low[u]=++num,ins[u]=1,s.push(u);
        for(int i=hd[u];i;i=nxt[i]){
            int v=to[i]; if(fl[i]!=inf) continue;
            if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
            else if(ins[v]) low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            if(s.top()==u) s.pop(),ins[u]=0;
            else{
                while(s.top()!=u) vis[s.top()]=1,ins[s.top()]=0,s.pop();
                vis[s.top()]=1,ins[s.top()]=0,s.pop(); 
            }
        }
        return;
    }
    
    int main(){
        N=read(),M=read();
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                int tp=calc(i,j);    
                A[tp]=read(); int nm=read();
                for(int k=1;k<=nm;k++){
                    int x=read(),y=read();
                    addedge(calc(x,y),tp,inf);
                }
            }
            for(int j=0;j<M-1;j++)
                addedge(calc(i,j),calc(i,j+1),inf);
        }
        for(int i=1;i<=N*M;i++)
            if(!dfn[i]) tarjan(i); 
        S=0,T=N*M+1; int sum=0;
        for(int i=0;i<N;i++)
            for(int j=0;j<M;j++){
                int tp=calc(i,j);
                if(vis[tp]) continue;
                if(A[tp]<0) addedge(tp,T,-A[tp]);
                else sum+=A[tp],addedge(S,tp,A[tp]);
            }    
        printf("%d
    ",sum-Dinic());
        return 0;
    }
    植物大战僵尸
  • 相关阅读:
    <转>Npoi导入导出Excel操作<载>
    将DataTable导出为Excel C#
    错误 X “X1”不包含“XX2”的定义,并且找不到可接受类型为“X1”的第一个参数的扩展方法“XX2”(是否缺少 using 指令或程序集引用?)
    错误 1 未知的服务器标记“asp:ScriptManager”。
    分析器错误消息: 类型“test.test.testx”不明确: 它可能来自程序集“F: estProjectin est.test.DLL”或程序集“F: estProjectin estProject.DLL”。请在类型名称中显式指定程序集。
    There are no interfaces on which a capture can be done.
    基础知识系列☞GET和POST→及相关知识
    基础知识系列☞Abstract和Virtual→及相关知识
    同源策略
    26Mybatis_一级缓存及其测试
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13206126.html
Copyright © 2020-2023  润新知