• bzoj1565: [NOI2009]植物大战僵尸


    其实一开始看到题意很长就不想做。。

    其实一开始想什么spfa什么DP什么的。。

    而这题是网络流(好像之前在竞赛室的时候听到队长骂这题stm网络流很难写,感觉还好啊,一中午写完了,2A)

    直接网络流显然搞不定,因为每个点有点值啊,费用流感觉也不对,想试试最小割,前天吃饭的时候突然想到:诶这题有负数?那搞搞最大权闭合子图!

    显然就正负分开st集合和ed集合,然后我就发现中间保护建的边要到inf,可最大权闭合子图不是sum-最小割吗?昨天走的时候O老师(%%%)才告诉我是正权sum-最小割

    然后就这样建,发现数据有环,那就要用topsort判环,但是有个要注意的,假如x被y保护,千万建边要建成y->x,如果建成x->y,假如x在环里面,那y的入度肯定不是0,但是实际上是y保护x,x无法被吃掉对于y是没有影响的。

    好感动。。。第二题最大权闭合子图居然看出来了而且2A。。。

    #include<cstdio>
    #include<iostream> 
    #include<cstring>
    using namespace std;
    
    int n,m,st,ed,sum;
    int w[610];
    
    struct enode
    {
        int x,y,next;
    }e[410000];int elen,elast[610];
    void eins(int x,int y)
    {
        elen++;
        e[elen].x=x;e[elen].y=y;
        e[elen].next=elast[x];elast[x]=elen;
    }
    
    int ru[610],top,sta[610];
    void topsort()
    {
        top=0;
        for(int i=1;i<=n*m+2;i++)
            if(ru[i]==0)sta[++top]=i;
            
        while(top!=0)
        {
            int x=sta[top];top--;
            for(int k=elast[x];k;k=e[k].next)
            {
                int y=e[k].y;
                ru[y]--;
                if(ru[y]==0)sta[++top]=y;
            }
        }
        
        sum=0;
        for(int i=1;i<=n*m;i++)
            if(ru[i]==0&&w[i]>=0)sum+=w[i];
    }
    
    
    struct node
    {
        int x,y,c,next,other;
    }a[810000];int len,last[610];
    void ins(int x,int y,int c)
    {
        int k1,k2;
        
        len++;k1=len;
        a[len].x=x;a[len].y=y;a[len].c=c;
        a[len].next=last[x];last[x]=len;
        
        len++;k2=len;
        a[len].x=y;a[len].y=x;a[len].c=0;
        a[len].next=last[y];last[y]=len;
        
        a[k1].other=k2;
        a[k2].other=k1;
    }
    void composition()
    {
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=elen;i++)
        {
            int x=e[i].x,y=e[i].y;
            if(ru[x]==0&&ru[y]==0)ins(x,y,999999999);
        }
        
        for(int i=1;i<=n*m;i++)
            if(ru[i]==0) 
                if(w[i]>=0)ins(i,ed,w[i]);
                else        ins(st,i,-w[i]);
    }
    
    int h[610],list[610];
    bool bt_h()
    {
        memset(h,0,sizeof(h));h[st]=1;
        int head=1,tail=2;list[1]=st;
        while(head!=tail)
        {
            int x=list[head];
            for(int k=last[x];k;k=a[k].next)
            {
                int y=a[k].y;
                if(h[y]==0&&a[k].c>0)
                {
                    h[y]=h[x]+1;
                    list[tail]=y;
                    tail++;
                }
            }
            head++;
        }
        if(h[ed]==0)return false;
        return true;
    }
    int findflow(int x,int f)
    {
        if(x==ed)return f;
        int s=0;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(h[y]==h[x]+1&&a[k].c>0&&s<f)
            {
                int t=findflow(y,min(a[k].c,f-s));
                s+=t;a[k].c-=t;a[a[k].other].c+=t;
            }
        }
        if(s==0)h[x]=0;
        return s;
    }
    
    int point(int x,int y){return x*m+y+1;}
    int main()
    {
        int T,x,y;
        scanf("%d%d",&n,&m);
        st=n*m+1;ed=n*m+2;
    
        elen=0;memset(elast,0,sizeof(elast));
        memset(ru,0,sizeof(ru));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                int p=point(i,j);
                scanf("%d",&w[p]);
                
                //我所能保护的 
                int pro;
                if(j!=0)
                {
                    pro=point(i,j-1);
                    eins(p,pro), ru[pro]++;
                }
                scanf("%d",&T);
                while(T--)
                {
                    scanf("%d%d",&x,&y);
                    pro=point(x,y);
                    eins(p,pro), ru[pro]++;
                }
            }
        }
        
        topsort();
        composition();
        
        int ans=0;
        while(bt_h()==true)
        {
            ans+=findflow(st,999999999);
        }
        printf("%d
    ",sum-ans);
        return 0;
    }
  • 相关阅读:
    sqoop 使用场景
    scala 类型和集合图
    scala 格式化操作
    sqoop 基础
    scala import 总结
    shell错误 syntax error: invalid arithmetic operator (error token is "
    C/C++ 隐式申明 问题
    阿里云贾扬清:数据湖正成为企业数据应用创新标配
    云原生时代如何用 Prometheus 实现性能压测可观测Metrics 篇
    基于 KubeVela 的机器学习实践
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/7878868.html
Copyright © 2020-2023  润新知