zoukankan      html  css  js  c++  java
  • bzoj4625: [BeiJing2016]水晶

    这题全靠一堆无关紧要的东西堆在一起防AC

    认真看看题,把那些有的没的扔一边去,其实给出约束条件,三个点不能同时取

    然后考虑用最小割

    这是个三分图。。。。然而并没有什么卵区别

    st连一组,ed连一组,然后中间拆点限制一下就好了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<map>
    using namespace std;
    const int inf=(1<<30)-1;
    
    struct node
    {
        int x,y,c,next;
    }a[2100000];int len,last[110000];
    void ins(int x,int y,int c)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].c=c;
        a[len].next=last[x];last[x]=len;
        
        len++;
        a[len].x=y;a[len].y=x;a[len].c=0;
        a[len].next=last[y];last[y]=len;
    }
    int h[110000],st,ed;
    int list[110000];
    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(a[k].c>0&&h[y]==0)
                {
                    h[y]=h[x]+1;
                    list[tail++]=y;
                }
            }
            head++;
        }
        return h[ed]!=0;
    }
    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(a[k].c>0&&h[y]==h[x]+1&&s<f)
            {
                int t=findflow(y,min(a[k].c,f-s));
                s+=t;a[k].c-=t;a[k^1].c+=t;
            }
        }
        if(s==0)h[x]=0;
        return s;
    }
    
    //-------------------------findflow-----------------------------------
    
    int n;
    struct point
    {
        int x,y,z;
        friend bool operator >(point p1,point p2){return p1.x==p2.x?(p1.y==p2.y?p1.z>p2.z:p1.y>p2.y):p1.x>p2.x;}
        friend bool operator <(point p1,point p2){return p1.x==p2.x?(p1.y==p2.y?p1.z<p2.z:p1.y<p2.y):p1.x<p2.x;}
    }p[51000],u,v; int d[51000];
    int color(point pp){return (pp.x+pp.y+pp.z)%3;}
    
    map<point,int>mp; int cc[3];
    void insert(point w,point u,point v)
    {
        cc[color(w)]=mp[w];
        cc[color(u)]=mp[u];
        cc[color(v)]=mp[v];
        ins(cc[1],cc[0],inf);
        ins(cc[0]+n,cc[2],inf);
    }
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int t,sum=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i].z,&d[i]);
            t=min(p[i].x,p[i].y),t=min(t,p[i].z);
            p[i].x-=t,p[i].y-=t,p[i].z-=t;
            
            if(color(p[i])==0)d[i]*=11;
            else d[i]*=10;
            sum+=d[i];
            
            if(mp.find(p[i])!=mp.end())
            {
                d[mp[p[i]]]+=d[i];
                i--,n--;
            }
            else mp[p[i]]=i;
        }
        
        len=1; st=2*n+1,ed=2*n+2;
        for(int i=1;i<=n;i++)
            if(color(p[i])==0)ins(i,i+n,d[i]);
            else if(color(p[i])==1)ins(st,i,d[i]);
            else ins(i,ed,d[i]);
        
        for(int i=1;i<=n;i++)
        {
            u=p[i],v=p[i];
            if(u.y>0||u.x==0||u.z==0)u.y++;
            else u.x--,u.z--;
            if(v.x>0)v.x--;
            else v.y++,v.z++;
            if(mp.find(u)!=mp.end()&&mp.find(v)!=mp.end())insert(p[i],u,v);
            
            u=p[i],v=p[i];
            if(u.y>0)u.y--;
            else u.x++,u.z++;
            if(v.x>0||v.y==0||v.z==0)v.x++;
            else v.y--,v.z--;
            if(mp.find(u)!=mp.end()&&mp.find(v)!=mp.end())insert(p[i],u,v);
            
            if(color(p[i])==0)
            {
                u=p[i],v=p[i];
                if(u.z>0||u.x==0||u.y==0)u.z++;
                else u.x--,u.y--;
                if(v.z>0)v.z--;
                else v.x++,v.y++;
                if(mp.find(u)!=mp.end()&&mp.find(v)!=mp.end())insert(p[i],u,v);
                
                u=p[i],v=p[i];
                if(u.x>0||u.y==0||u.z==0)u.x++;
                else u.y--,u.z--;
                if(v.x>0)v.x--;
                else v.y++,v.z++;
                if(mp.find(u)!=mp.end()&&mp.find(v)!=mp.end())insert(p[i],u,v);
                
                u=p[i],v=p[i];
                if(u.y>0||u.x==0||u.z==0)u.y++;
                else u.x--,u.z--;
                if(v.y>0)v.y--;
                else v.x++,v.z++;
                if(mp.find(u)!=mp.end()&&mp.find(v)!=mp.end())insert(p[i],u,v);
            }
        }
        
        int ans=0;
        while(bt_h())
        {
            ans+=findflow(st,inf);
        }
        printf("%.1lf
    ",double(sum-ans)/10.0);
        
        return 0;
    }
  • 相关阅读:
    LeetCode 32. 最长有效括号(Longest Valid Parentheses)
    LeetCode 141. 环形链表(Linked List Cycle)
    LeetCode 160. 相交链表(Intersection of Two Linked Lists)
    LeetCode 112. 路径总和(Path Sum)
    LeetCode 124. 二叉树中的最大路径和(Binary Tree Maximum Path Sum)
    LightGBM新特性总结
    sql service 事务与锁
    C#泛型实例详解
    C# 中的委托和事件(详解)
    C# DateTime日期格式化
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10235835.html
Copyright © 2011-2022 走看看