• 【BZOJ 3218】 3218: a + b Problem(最小割+可持久化线段树)


     

     

    3218: a + b Problem

    Time Limit: 20 Sec  Memory Limit: 40 MB
    Submit: 1440  Solved: 545

    Description

    Input

    Output

    Sample Input

    Sample Output

    HINT

    Source

    【分析】

      这题建图很神哦!

      其实只是边的合并。

      就是说,原本海陆型建图就好了的。

      

      但是这样有一点问题,就是pj只算一次的,但是这样跑算了很多次。

      改一改图。

      

      这样就好了。

      但是边很多。

      一开始没注意那个l~r的,就觉得嗯,开一些辅助点合并一下边。

      后来发现还有l~r的限制,其实也是开一些辅助点合并一下边,但是这里就有点高级了。

      就是值考虑l<=a<=r的话就是开个权值线段树然后用线段树上的点作为辅助点。

      但是还有一个条件是i<=j的时候才算,所以是可持久化线段树。

      关于辅助点,其实上面的j‘就是辅助点,照着做就好了。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 5010
      9 #define Maxm 1000000000
     10 // #define Maxm 10
     11 #define INF 0x7fffffff
     12 // #define LL long long
     13 
     14 int mymin(int x,int y) {return x<y?x:y;}
     15 
     16 struct node
     17 {
     18     int x,y,f,o,next;
     19 }t[Maxn*210];
     20 int len,first[Maxn*40];
     21 
     22 void ins(int x,int y,int f)
     23 {
     24     if(y==0) return;
     25     t[++len].x=x;t[len].y=y;t[len].f=f;
     26     t[len].next=first[x];first[x]=len;t[len].o=len+1;
     27     t[++len].x=y;t[len].y=x;t[len].f=0;
     28     t[len].next=first[y];first[y]=len;t[len].o=len-1;
     29 }
     30 
     31 int dis[Maxn*40],st,ed;
     32 queue<int > q;
     33 bool bfs()
     34 {
     35     memset(dis,-1,sizeof(dis));
     36     while(!q.empty()) q.pop();
     37     dis[st]=0;q.push(st);
     38     while(!q.empty())
     39     {
     40         int x=q.front();
     41         for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     42         {
     43             int y=t[i].y;
     44             if(dis[y]==-1)
     45             {
     46                 dis[y]=dis[x]+1;
     47                 q.push(y);
     48             }
     49         }
     50         q.pop();
     51     }
     52     if(dis[ed]==-1) return 0;
     53     return 1;
     54 }
     55 
     56 int ffind(int x,int flow)
     57 {
     58     if(x==ed) return flow;
     59     int now=0;
     60     for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     61     {
     62         int y=t[i].y;
     63         if(dis[y]==dis[x]+1)
     64         {
     65             int a=ffind(y,mymin(flow-now,t[i].f));
     66             t[i].f-=a;
     67             t[t[i].o].f+=a;
     68             now+=a;
     69         }
     70         if(now==flow) break;
     71     }
     72     if(now==0) dis[x]=-1;
     73     return now;
     74 }
     75 
     76 int ans=0;
     77 void max_flow()
     78 {
     79     while(bfs())
     80     {
     81         ans-=ffind(st,INF);
     82     }
     83 }
     84 void output()
     85 {
     86     for(int i=1;i<=len;i+=2)
     87     {
     88         printf("%d -> %d %d
    ",t[i].x,t[i].y,t[i].f);
     89     }printf("
    ");
     90 }
     91 
     92 int rt[Maxn],cnt;
     93 struct nnode
     94 {
     95     int lc,rc;
     96 }tr[Maxn*40];
     97 
     98 
     99 void add(int l,int r,int x,int y,int a,int id)
    100 {
    101     ins(y,x,INF);
    102     ins(y,id,INF);
    103     if(l==r) return;
    104     int mid=(l+r)>>1;
    105     if(a<=mid)
    106     {
    107         tr[y].lc=++cnt;tr[y].rc=tr[x].rc;
    108         add(l,mid,tr[x].lc,tr[y].lc,a,id);
    109     }
    110     else
    111     {
    112         tr[y].rc=++cnt;tr[y].lc=tr[x].lc;
    113         add(mid+1,r,tr[x].rc,tr[y].rc,a,id);
    114     }
    115 }
    116 
    117 void add2(int l,int r,int x,int al,int ar,int id)
    118 {
    119     if(l==al&&r==ar)
    120     {
    121         ins(id,x,INF);
    122         return;
    123     }
    124     int mid=(l+r)>>1;
    125     if(ar<=mid) add2(l,mid,tr[x].lc,al,ar,id);
    126     else if(al>mid) add2(mid+1,r,tr[x].rc,al,ar,id);
    127     else
    128     {
    129         add2(l,mid,tr[x].lc,al,mid,id);
    130         add2(mid+1,r,tr[x].rc,mid+1,ar,id);
    131     }
    132 }
    133 
    134 
    135 int main()
    136 {
    137     int n;
    138     scanf("%d",&n);
    139     st=n*2+1,ed=st+1;cnt=ed;
    140     rt[0]=0;
    141     len=0;
    142     memset(first,0,sizeof(first));
    143     for(int i=1;i<=n;i++)
    144     {
    145         int a,b,c,w,al,ar,p;
    146         scanf("%d%d%d%d%d%d",&a,&b,&w,&al,&ar,&p);
    147         ans+=b+w;
    148         ins(st,i,b);ins(i,ed,w);
    149         ins(i,i+n,p);
    150         rt[i]=++cnt;
    151         add(0,Maxm,rt[i-1],rt[i],a,i);
    152         add2(0,Maxm,rt[i],al,ar,i+n);
    153     }
    154     // output();
    155     max_flow();
    156     printf("%d
    ",ans);
    157     return 0;
    158 }
    View Code

    2017-04-06 22:05:14

  • 相关阅读:
    文件的上传
    JSP基础知识
    AJAX
    Listener
    Filter(一)
    session
    网络爬虫(9)-xpath解析
    网络爬虫(8)-正则表达式
    网络爬虫(7)-beautifulSoup解析库
    网络爬虫(6)-Requests库
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6675690.html
Copyright © 2020-2023  润新知