bzoj 3218: a + b Problem
生活随笔
收集整理的這篇文章主要介紹了
bzoj 3218: a + b Problem
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
?
Input
Output
Sample Input
100 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\n",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\n",ans); 106 } 107 int main() 108 { 109 //freopen("pp.in","r",stdin); 110 work(); 111 return 0; 112 } 主席樹維護的網絡流?
轉載于:https://www.cnblogs.com/Yuzao/p/7219922.html
總結
以上是生活随笔為你收集整理的bzoj 3218: a + b Problem的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第三百一十九节,Django框架,文件上
- 下一篇: ThreadLocal相关