zoukankan      html  css  js  c++  java
  • bzoj 3218: a + b Problem

    Description

    Input

     

    Output

     

    Sample 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

    Sample Output

    55
     
    题解:
    这题要好好总结,真是抓狂的A+B problem.
    首先非常容易想到O(n^2)空间复杂度的网络流建图,和为了博多一题类似(SUM-不合法),区别在于中间那条双向边改成单向边.
    因为一个点只有一次被认为是奇怪方格的机会,所以拆点(i',i,p[i]),限制p[i],所以枚举前i个点,满足条件就连边到i'
    综上:
    连(S,i,w[i])(i,T,b[i])(i',i,p[i]) 如果满足条件的j (j,i',inf)
    这样空间显然不允许,然后就来了奇怪的主席树上跑网络流,直接建好树以后把(j,i',inf)改成j连主席树上的点即可
    被i覆盖的区间我们就在主席树上向j’连边 大致图如下 对所有点都做相同处理:
    HINT:
    1.傻逼错误:为了省内存num初值设为-1....然后for里没改.
    2.很重要的地方:i连向的旧节点要对新节点建边,不然在主席树上无法流通
     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 using namespace std;
     8 const int N=12333,M=3200005,inf=2e9;
     9 typedef long long ll;
    10 int head[N],num=-1;
    11 struct Lin{
    12     int next,to,dis;
    13 }a[M];
    14 int gi(){
    15     int str=0;char ch=getchar();
    16     while(ch>'9' || ch<'0')ch=getchar();
    17     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
    18     return str;
    19 }
    20 void init(int x,int y,int dis){
    21     a[++num].next=head[x];a[num].to=y;a[num].dis=dis;head[x]=num;
    22 }
    23 void addedge(int x,int y,int dis){
    24     init(x,y,dis);init(y,x,0);
    25 }
    26 int n,s[N],q[N],b[N],w[N],l[N],r[N],p[N],S=0,T,dep[N];
    27 bool bfs(){
    28     memset(dep,0,sizeof(dep));
    29     int u,x,t=0,sum=1;
    30     q[1]=S;dep[S]=1;
    31     while(t!=sum){
    32         x=q[++t];
    33         for(int i=head[x];i;i=a[i].next){
    34             u=a[i].to;
    35             if(dep[u] || a[i].dis<=0)continue;
    36             dep[u]=dep[x]+1;q[++sum]=u;
    37         }
    38     }
    39     return dep[T];
    40 }
    41 int dfs(int x,int flow){
    42     if(!flow || x==T)return flow;
    43     int tmp,tot=0,u;
    44     for(int i=head[x];i;i=a[i].next){
    45         u=a[i].to;
    46         if(dep[u]!=dep[x]+1 || a[i].dis<=0)continue;
    47         tmp=dfs(u,min(flow,a[i].dis));
    48         a[i].dis-=tmp;a[i^1].dis+=tmp;
    49         tot+=tmp;flow-=tmp;
    50         if(!flow)break;
    51     }
    52     if(!tot)dep[x]=0;
    53     return tot;
    54 }
    55 int maxflow(){
    56     int tot=0,tmp;
    57     while(bfs()){
    58         tmp=dfs(S,inf);
    59         while(tmp)tot+=tmp,tmp=dfs(S,inf);
    60     }
    61     return tot;
    62 }
    63 void work(){
    64     n=gi();T=2*n+1;ll ans=0;
    65     for(int i=1;i<=n;i++){
    66         s[i]=gi();b[i]=gi();w[i]=gi();l[i]=gi();r[i]=gi();p[i]=gi();
    67         ans+=b[i]+w[i];
    68     }
    69     for(int i=1;i<=n;i++){
    70         addedge(S,i,w[i]);addedge(i,T,b[i]);addedge(i+n,i,p[i]);
    71         for(int j=1;j<i;j++){
    72             if(l[i]<=s[j] && s[j]<=r[i])addedge(j,i+n,p[i]);
    73         }
    74     }
    75     ans=ans-maxflow();
    76     printf("%lld
    ",ans);
    77 }
    78 int main()
    79 {
    80     freopen("pp.in","r",stdin);
    81     work();
    82     return 0;
    83 }
    朴素做法
      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 using namespace std;
      8 const int N=303333,M=820005,inf=2e9;
      9 typedef long long ll;
     10 int head[N],num=1,cnt=0,lim=0;
     11 struct Lin{
     12     int next,to,dis;
     13 }a[M];
     14 int gi(){
     15     int str=0;char ch=getchar();
     16     while(ch>'9' || ch<'0')ch=getchar();
     17     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
     18     return str;
     19 }
     20 void init(int x,int y,int dis){
     21     a[++num].next=head[x];a[num].to=y;a[num].dis=dis;head[x]=num;
     22 }
     23 void addedge(int x,int y,int dis){
     24     init(x,y,dis);init(y,x,0);
     25 }
     26 int n,s[N],q[N],b[N],w[N],L[N],R[N],p[N],S=0,T,dep[N];
     27 bool bfs(){
     28     memset(dep,0,sizeof(dep));
     29     int u,x,t=0,sum=1;
     30     q[1]=S;dep[S]=1;
     31     while(t!=sum){
     32         x=q[++t];
     33         for(int i=head[x];i;i=a[i].next){
     34             u=a[i].to;
     35             if(dep[u] || a[i].dis<=0)continue;
     36             dep[u]=dep[x]+1;q[++sum]=u;
     37         }
     38     }
     39     return dep[T];
     40 }
     41 int dfs(int x,int flow){
     42     if(!flow || x==T)return flow;
     43     int tmp,tot=0,u;
     44     for(int i=head[x];i;i=a[i].next){
     45         u=a[i].to;
     46         if(dep[u]!=dep[x]+1 || a[i].dis<=0)continue;
     47         tmp=dfs(u,min(flow,a[i].dis));
     48         a[i].dis-=tmp;a[i^1].dis+=tmp;
     49         tot+=tmp;flow-=tmp;
     50         if(!flow)break;
     51     }
     52     if(!tot)dep[x]=0;
     53     return tot;
     54 }
     55 int maxflow(){
     56     int tot=0,tmp;
     57     while(bfs()){
     58         tmp=dfs(S,inf);
     59         while(tmp)tot+=tmp,tmp=dfs(S,inf);
     60     }
     61     return tot;
     62 }
     63 struct Segtree{
     64     int ls,rs;
     65 }Tree[N<<1];
     66 int root[N];
     67 void updata(int &rt,int last,int l,int r,int ask,int id){
     68     rt=++cnt;Tree[rt]=Tree[last];
     69     if(l==r){
     70         addedge(id,rt+T,inf);
     71         if(last)addedge(last+T,rt+T,inf);
     72         return ;
     73     }
     74     int mid=(l+r)>>1;
     75     if(ask<=mid)updata(Tree[rt].ls,Tree[last].ls,l,mid,ask,id);
     76     else updata(Tree[rt].rs,Tree[last].rs,mid+1,r,ask,id);
     77     if(Tree[rt].ls)addedge(Tree[rt].ls+T,rt+T,inf);if(Tree[rt].rs)addedge(Tree[rt].rs+T,rt+T,inf);
     78 }
     79 void query(int rt,int l,int r,int sa,int se,int id){
     80     if(!rt)return ;
     81     if(sa<=l && r<=se){
     82         addedge(rt+T,id+n,inf);
     83         return ;
     84     }
     85     int mid=(l+r)>>1;
     86     if(sa<=mid)query(Tree[rt].ls,l,mid,sa,se,id);
     87     if(se>mid)query(Tree[rt].rs,mid+1,r,sa,se,id);
     88 }
     89 void build(){
     90     for(int i=1;i<=n;i++){
     91         addedge(S,i,w[i]);addedge(i+n,i,p[i]);addedge(i,T,b[i]);
     92         if(i>1)query(root[i-1],0,lim,L[i],R[i],i);
     93         updata(root[i],root[i-1],0,lim,s[i],i);
     94     }
     95 }
     96 void work(){
     97     n=gi();T=2*n+1;ll ans=0;
     98     for(int i=1;i<=n;i++){
     99         s[i]=gi();b[i]=gi();w[i]=gi();L[i]=gi();R[i]=gi();p[i]=gi();
    100         if(R[i]>lim)lim=R[i];if(L[i]>lim)lim=L[i];if(s[i]>lim)lim=s[i];
    101         ans+=b[i]+w[i];
    102     }
    103     build();
    104     ans=ans-maxflow();
    105     printf("%lld
    ",ans);
    106 }
    107 int main()
    108 {
    109     //freopen("pp.in","r",stdin);
    110     work();
    111     return 0;
    112 }
    主席树维护的网络流
  • 相关阅读:
    EBS中的采购单据状态及其控制
    详解EBS接口开发之采购接收&退货处理之关键API--(补充)
    数据挖掘系列
    如果看了这篇文章你还不懂傅里叶变换,那就过来掐死我吧
    机器学习中的数学
    一个机器学习博客 ,包括 Standford公开课machine learning
    机器学习流行算法一览
    java se 另一博客
    java 正则
    java map
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7219922.html
Copyright © 2011-2022 走看看