• hdu 4859 最大点权独立集的变形(方格取数的变形)


    /*刚开始不会写,最大点权独立集神马都不知道,在潘神的指导下终于做出来,灰常感谢ps;
    和方格取数差不多奇偶建图,对于D必割点权为0,对于.必然不割点权为inf。然后和方格取数差不多的建图
    .--.||E权值为2,,.||E--D权值为0.
    最大点权独立集=sum-最小点权覆盖。
    */
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    #define inf 0x3fffffff
    #define ii 50
    #define N   3000
    struct node {
     int u,v,w,next;
    }bian[N*6];
    int head[N],yong,s,t,dis[N];
    void init(){
    yong=0;
    memset(head,-1,sizeof(head));
    memset(dis,-1,sizeof(dis));
    }
    void addedge(int u,int v,int w) {
    bian[yong].u=u;
    bian[yong].v=v;
    bian[yong].w=w;
    bian[yong].next=head[u];
    head[u]=yong++;
    }
    void add(int u,int v,int w) {
     addedge(u,v,w);
     addedge(v,u,0);
    }
    void bfs() {
    int u,v,i;
    queue<int>q;
    q.push(t);
    dis[t]=0;
    while(!q.empty()) {
        u=q.front();
        q.pop();
        for(i=head[u];i!=-1;i=bian[i].next) {
            v=bian[i].v;
            if(dis[v]==-1) {
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
    }
    return ;
    }
    int ISAP() {
    int sum=0;
    bfs();
    int  gap[N],cur[N],stac[N],top,i;
    memset(gap,0,sizeof(gap));
    for(i=s;i<=t;i++) {
        gap[dis[i]]++;
        cur[i]=head[i];
    }
    int k=s;
    top=0;
    while(dis[s]<t+1) {
         if(k==t) {
                int minn=inf,index;
            for(i=0;i<top;i++) {
                int e=stac[i];
                if(minn>bian[e].w) {
                    minn=bian[e].w;
                    index=i;
                }
            }
            for(i=0;i<top;i++) {
                int e=stac[i];
                bian[e].w-=minn;
                bian[e^1].w+=minn;
            }
            sum+=minn;
            top=index;
            k=bian[stac[top]].u;
         }
         for(i=cur[k];i!=-1;i=bian[i].next) {
           int  v=bian[i].v;
            if(bian[i].w&&dis[k]==dis[v]+1) {
                cur[k]=i;
                k=v;
                stac[top++]=i;
                break;
            }
         }
         if(i==-1) {
            int m=t+1;
            for(i=head[k];i!=-1;i=bian[i].next)
                if(m>dis[bian[i].v]&&bian[i].w) {
                    m=dis[bian[i].v];
                    cur[k]=i;
                }
                if(--gap[dis[k]]==0)break;
                gap[dis[k]=m+1]++;
                if(k!=s)
                    k=bian[stac[--top]].u;
         }
    }
    return sum;
    }
    int main() {
        int n,m,i,j,T,id[ii][ii],cnt,sum,f=0;
        char ss[ii][ii];
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            cnt=1;sum=0;
            init();
            for(i=1;i<=n;i++) {
                scanf("%s",ss[i]+1);
                for(j=1;j<=m;j++) {
                    if(ss[i][j]=='.'||ss[i][j]=='E')//记录总数
                        sum+=4;
                    id[i][j]=cnt++;
                }
            }
            s=0;t=n*m+1;
            for(i=1;i<=n;i++)
            for(j=1;j<=m;j++) {
                if((i+j)&1) {//奇偶建图与源点相连
                    if(ss[i][j]=='.')
                        add(s,id[i][j],inf);//必然不割
                    if(ss[i][j]=='D')//必割
                        add(s,id[i][j],0);
                    if(ss[i][j]=='E')//任意选择
                        add(s,id[i][j],4);
                    if(i>=2) {
                        if(ss[i][j]=='.'||ss[i][j]=='E') {
                            if(ss[i-1][j]=='.'||ss[i-1][j]=='E')add(id[i][j],id[i-1][j],2);//
                            if(ss[i-1][j]=='D')add(id[i][j],id[i-1][j],0);//
                        }
                        else
                            add(id[i][j],id[i-1][j],0);
                    }
                    if(j>=2) {
                       if(ss[i][j]=='.'||ss[i][j]=='E') {
                            if(ss[i][j-1]=='.'||ss[i][j-1]=='E')add(id[i][j],id[i][j-1],2);
                            if(ss[i][j-1]=='D')add(id[i][j],id[i][j-1],0);
                        }
                        else
                            add(id[i][j],id[i][j-1],0);
                    }
                    if(i<=n-1){
                         if(ss[i][j]=='.'||ss[i][j]=='E') {
                            if(ss[i+1][j]=='.'||ss[i+1][j]=='E')add(id[i][j],id[i+1][j],2);
                            if(ss[i+1][j]=='D')add(id[i][j],id[i+1][j],0);
                        }
                        else
                            add(id[i][j],id[i+1][j],0);
                    }
                    if(j<=m-1) {
                          if(ss[i][j]=='.'||ss[i][j]=='E') {
                            if(ss[i][j+1]=='.'||ss[i][j+1]=='E')add(id[i][j],id[i][j+1],2);
                            if(ss[i][j+1]=='D')add(id[i][j],id[i][j+1],0);
                            }
                        else
                            add(id[i][j],id[i][j+1],0);
                    }
                }
                else {//与汇点相连
                    if(ss[i][j]=='.')
                        add(id[i][j],t,inf);
                    if(ss[i][j]=='E')
                        add(id[i][j],t,4);
                    if(ss[i][j]=='D')
                        add(id[i][j],t,0);
                }
            }
            printf("Case %d: ",++f);
            printf("%d
    ",sum-ISAP());
        }
    return 0;
    }
    

  • 相关阅读:
    CentOS7.0下Zabbix3.4至Zabbix4.0的升级步骤(Proxy)
    CentOS6.5下Zabbix3.0升级到4.0
    kubernetes相关概念
    更新OpenSSL
    fish 常用主题推荐
    [转] Adobe acrobat 破解教程
    [转]latex符号
    bank conflct 一句话总结
    Ubuntu 安装boost 库
    ubuntu 16.04安装nVidia显卡驱动和cuda/cudnn踩坑过程
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410657.html
Copyright © 2020-2023  润新知