zoukankan      html  css  js  c++  java
  • UOJ#77. A+B Problem

    题目名称是吸引你点进来的。

    从前有个 n 个方格排成一行,从左至右依此编号为 1,2,,n

    有一天思考熊想给这 n 个方格染上黑白两色。

    第 i 个方格上有 6 个属性:ai,bi,wi,li,ri,pi

    如果方格 i 染成黑色就会获得 bi 的好看度。

    如果方格 i 染成白色就会获得 wi 的好看度。

    但是太多了黑色就不好看了。如果方格 i 是黑色,并且存在一个 j 使得 1j<i 且 liajri 且方格 j 为白色,那么方格 i 就被称为奇怪的方格。

    如果方格 i 是奇怪的方格,就会使总好看度减少 pi

    也就是说对于一个染色方案,好看度为:

    方格i为黑色bi+方格i为白色wi方格i为奇怪的方格pi

    现在给你 n,a,b,w,l,r,p,问所有染色方案中最大的好看度是多少。

    输入格式

    第一行一个正整数 n

    接下来 n 行中第 i 行有用空格隔开的 6 个非负整数依次表示 ai,bi,wi,li,ri,pi

    保证 liri

    输出格式

    一个非负整数表示所有染色方案中最大的好看度。

    样例一

    input

    10
    0 1 7 3 9 2
    7 4 0 9 10 5
    1 0 4 2 10 2
    7 9 1 5 7 2
    6 3 5 3 6 2
    6 6 4 1 8 1
    6 1 6 0 6 5
    2 2 5 0 9 3
    5 1 3 0 2 5
    5 6 7 1 1 2
    
    

    output

    55
    
    

    explanation

    最优染色方案为:白 黑 白 黑 白 黑 白 白 白 白

    可以发现只有方格 6 为奇怪的方格。

    所以好看度为:

    ==w1+b2+w3+b4+w5+b6+w7+w8+w9+w10p67+4+4+9+5+6+6+5+3+7155

    限制与约定

    设 amax 为 a,l,r 中的最大值,vmax 为 b,w 中的最大值, pmax 为 p 中的最大值。

    测试点编号namaxvmaxpmax
    1 =5 10 10 10
    2 =20 40 40 40
    3 =20 40 40 40
    4 =5000 10 200000 100000
    5 =5000 10 200000 300000
    6 =200 109 200000 200000
    7 =300 109 200000 220000
    8 =500 109 200000 400000
    9 =5000 5000 200000 150000
    10 =5000 109 200000 300000

    时间限制:2s

    空间限制:48MB

    来源

    VFleaKing

    看WZJ这蒟蒻卡爆测评机2333333

    都在这里了http://oj.cnuschool.org.cn/oj/home/educationArchiveList.htm    A+B,登陆后下载

    由于我现推的,和VFK论文中的写的正好相反。

    暴力:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #include<queue>
    #define rep(s,t) for(int i=s;i<=t;i++)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    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;
    }
    const int maxn=100010;
    const int maxm=200010;
    struct Dinic {
        int n,m,s,t,nowd;
        int vis[maxn],d[maxn],cur[maxn],first[maxn],next[maxm];
        struct Edge {int from,to,flow;}edges[maxm];
        void init(int n) {
            this->n=n;m=0;
            fill(first+1,first+n+1,-1);
        }
        void AddEdge(int u,int v,int w) {
            edges[m]=(Edge){u,v,w};next[m]=first[u];first[u]=m++;
            edges[m]=(Edge){v,u,0};next[m]=first[v];first[v]=m++;
        }
        int BFS() {
            queue<int> Q;
            Q.push(s);d[s]=0;vis[s]=++nowd;
            while(!Q.empty()) {
                int x=Q.front();Q.pop();cur[x]=first[x];
                ren {
                    Edge& e=edges[i];
                    if(e.flow&&vis[e.to]!=nowd) {
                        vis[e.to]=nowd;
                        d[e.to]=d[x]+1;
                        Q.push(e.to);    
                    }
                }
             }
             return vis[t]==nowd;
        }
        int DFS(int x,int a) {
            if(x==t||!a) return a;
            int flow=0,f;
            for(int& i=cur[x];i!=-1;i=next[i]) {
                Edge& e=edges[i];
                if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(e.flow,a)))) {
                    flow+=f;a-=f;
                    e.flow-=f;edges[i^1].flow+=f;
                    if(!a) break;
                }
            }
            return flow;
        }
        int solve(int s,int t) {
            this->s=s;this->t=t;
            int flow=0;
            while(BFS()) flow+=DFS(s,1e9);
            return flow;
        }
    }sol;
    int n,a[maxn],b[maxn],w[maxn],l[maxn],r[maxn],p[maxn];
    void solve() {
        int S=2*n+1,T=2*n+2,all=0;sol.init(T);
        rep(1,n) sol.AddEdge(S,i,w[i]),sol.AddEdge(i,T,b[i]),all+=w[i]+b[i];
        rep(1,n) {
            for(int j=1;j<i;j++) if(l[i]<=a[j]&&a[j]<=r[i]) sol.AddEdge(j,i+n,1e9);
            sol.AddEdge(i+n,i,p[i]);
        }
        printf("%d
    ",all-sol.solve(S,T));
    }
    int main() {
        n=read();
        rep(1,n) a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read();
        solve();
        return 0;
    }
    View Code

    正解:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #include<queue>
    #define rep(s,t) for(int i=s;i<=t;i++)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    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;
    }
    const int maxn=100010;
    const int maxm=400010;
    struct Dinic {
        int n,m,s,t,nowd;
        int vis[maxn],d[maxn],cur[maxn],first[maxn],next[maxm];
        struct Edge {int from,to,flow;}edges[maxm];
        void init() {
            m=0;
            memset(first,-1,sizeof(first));
        }
        void AddEdge(int u,int v,int w) {
            if(!u||!v) return;
            edges[m]=(Edge){u,v,w};next[m]=first[u];first[u]=m++;
            edges[m]=(Edge){v,u,0};next[m]=first[v];first[v]=m++;
        }
        int BFS() {
            queue<int> Q;
            Q.push(s);d[s]=0;vis[s]=++nowd;
            while(!Q.empty()) {
                int x=Q.front();Q.pop();cur[x]=first[x];
                ren {
                    Edge& e=edges[i];
                    if(e.flow&&vis[e.to]!=nowd) {
                        vis[e.to]=nowd;
                        d[e.to]=d[x]+1;
                        Q.push(e.to);    
                    }
                }
             }
             return vis[t]==nowd;
        }
        int DFS(int x,int a) {
            if(x==t||!a) return a;
            int flow=0,f;
            for(int& i=cur[x];i!=-1;i=next[i]) {
                Edge& e=edges[i];
                if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(e.flow,a)))) {
                    flow+=f;a-=f;
                    e.flow-=f;edges[i^1].flow+=f;
                    if(!a) break;
                }
            }
            return flow;
        }
        int solve(int s,int t) {
            this->s=s;this->t=t;
            int flow=0;
            while(BFS()) flow+=DFS(s,1e9);
            return flow;
        }
    }sol;
    int n,a[5010],b[5010],w[5010],l[5010],r[5010],p[5010];
    int root[maxn],ls[maxn],rs[maxn],ToT;
    void build(int& y,int x,int l,int r,int pos,int v) {
        y=++ToT;
        if(l==r) {
            if(x) sol.AddEdge(x,y,1e9);
            sol.AddEdge(v,y,1e9);
            return;
        }
        int mid=l+r>>1;ls[y]=ls[x];rs[y]=rs[x];
        if(pos<=mid) build(ls[y],ls[x],l,mid,pos,v);
        else build(rs[y],rs[x],mid+1,r,pos,v);
        if(ls[y]) sol.AddEdge(ls[y],y,1e9);
        if(rs[y]) sol.AddEdge(rs[y],y,1e9);
    }
    void query(int y,int l,int r,int ql,int qr,int v) {
        if(!y) return;
        if(ql<=l&&r<=qr) {sol.AddEdge(y,v,1e9);return;}
        int mid=l+r>>1;
        if(ql<=mid) query(ls[y],l,mid,ql,qr,v);
        if(qr>mid) query(rs[y],mid+1,r,ql,qr,v);
    }
    int tmp[15010],cnt;
    void pre() {
        int m=0;
        rep(1,n) tmp[++m]=a[i],tmp[++m]=l[i],tmp[++m]=r[i];
        sort(tmp+1,tmp+m+1);cnt=m;
        rep(1,n) a[i]=lower_bound(tmp+1,tmp+m+1,a[i])-tmp;
        rep(1,n) l[i]=lower_bound(tmp+1,tmp+m+1,l[i])-tmp;
        rep(1,n) r[i]=lower_bound(tmp+1,tmp+m+1,r[i])-tmp;
    }
    void solve() {
        int S=2*n+1,T=2*n+2,all=0;sol.init();ToT=T;
        rep(1,n) sol.AddEdge(S,i,w[i]),sol.AddEdge(i,T,b[i]),all+=w[i]+b[i];
        rep(1,n) {
            query(root[i],1,cnt,l[i],r[i],i+n);
            sol.AddEdge(i+n,i,p[i]);build(root[i+1],root[i],1,cnt,a[i],i);
        }
        printf("%d
    ",all-sol.solve(S,T));
    }
    int main() {
        n=read();
        rep(1,n) a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read();
        pre();solve();
        return 0;
    }
    View Code
  • 相关阅读:
    简单自定义控件在view下可以运行在传统模式下运行显示空白
    symbian菜单2运行时更换菜单实现右键菜单功能
    得到文件路径信息 TParse
    Symbian菜单:创建一个最简单的菜单
    RFs 目录操作
    作品[RFileRead/WriteStream 练习] for s60 fp2
    对话框的练习
    文件浏览工具s60第二版
    转描述符
    得到驱动器信息
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4652157.html
Copyright © 2011-2022 走看看