数据范围:$n≤5000$,$a,l,r≤10^9$,$b,w,p≤2\times 10^5$。
我们考虑一种暴力的最小割做法:
首先令$sum=\sum\limits_{i=1}^{n} b_i+w_i$
我们建一个图:
$S->i$,边权为$w_i$
$i->T$,边权为$b_i$
$i->i'$,边权为$p_i$
$j->i'$,边权为$∞$,(这里的i和j需要满足题目中的i,j限制)
然后我们对这个图跑一遍最小割,将$sum$减去这个值输出就是答案了。
这么建图总共需要$2n+2$个点,$O(n^2)$条边
1 #include<bits/stdc++.h> 2 #define M 1000005 3 #define N 150005 4 #define INF 19890604 5 using namespace std; 6 7 struct edge{int u,v,next;}e[M]={0}; int head[N]={0},use=0; 8 void add(int x,int y,int z){e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use++;} 9 void ADD(int x,int y,int z){add(x,y,z); add(y,x,0);} 10 11 int dis[N]={0},S,T; queue<int> q; 12 13 bool bfs(){ 14 memset(dis,0,sizeof(dis)); 15 q.push(S); dis[S]=1; 16 while(!q.empty()){ 17 int u=q.front(); q.pop(); 18 for(int i=head[u];~i;i=e[i].next) 19 if(e[i].v&&dis[e[i].u]==0){ 20 dis[e[i].u]=dis[u]+1; 21 q.push(e[i].u); 22 } 23 } 24 return dis[T]; 25 } 26 27 int dfs(int x,int flow){ 28 if(x==T) return flow; int sum=0; 29 for(int i=head[x];~i;i=e[i].next) 30 if(e[i].v&&dis[x]+1==dis[e[i].u]){ 31 int k=dfs(e[i].u,min(flow,e[i].v)); 32 e[i].v-=k; e[i^1].v+=k; 33 sum+=k; flow-=k; 34 if(flow==0) return sum; 35 } 36 if(flow==0) dis[x]=-1; 37 return sum; 38 } 39 40 int dinic(){ 41 int res=0; 42 while(bfs()) 43 res+=dfs(S,1<<30); 44 return res;} 45 46 int n,sum=0; 47 int a[N]={0},b[N]={0},w[N]={0},l[N]={0},r[N]={0},p[N]={0},ok[N]={0}; 48 49 int main(){ 50 scanf("%d",&n); 51 for(int i=1;i<=n;i++){ 52 scanf("%d%d%d%d%d%d",a+i,b+i,w+i,l+i,r+i,p+i); 53 sum+=b[i]+w[i]; 54 } 55 S=0,T=2*n+1; 56 memset(head,-1,sizeof(head)); 57 for(int i=1;i<=n;i++) ADD(S,i,w[i]),ADD(i,T,b[i]),ADD(i+n,i,p[i]); 58 for(int i=1;i<=n;i++) for(int j=1;j<i;j++) 59 if(l[i]<=a[j]&&a[j]<=r[i]) 60 ADD(j,i+n,INF); 61 cout<<sum-dinic()<<endl; 62 }