区间k覆盖费用流模板题。
离散化后让每个数字最多可用k次即可,源点向起点连边,终点向汇点连边,第i个点向第i+1个点连边,容量都为k,费用为0。
对于给的左闭右开区间,区间左端点向右端点连边,容量为1,费用为-val。
#include <bits/stdc++.h> using namespace std; int _,n,k,m; const int N = 1e3+7; const int inf = 2147483647; struct edge { int from,to,cap,flow,cost; edge(int u,int v,int c,int co) { from=u; to=v; cap=c,flow=0; cost=co; } }; struct MCMF { vector<int> G[N];//存每个点的边 vector<edge> es;//存所有的边 int inq[N];//判断是否在队列中 int d[N];//距离 int p[N],a[N];//上一条弧与可改进量 void init(int t) { for(int i=0; i<=t+10; i++) G[i].clear(); es.clear(); } void addedge(int u,int v,int c,int co) { es.push_back(edge(u,v,c,co)); es.push_back(edge(v,u,0,-co)); int m=es.size(); G[u].push_back(m-2); G[v].push_back(m-1); } bool SPFA(int s,int t,int &flow,int &cost) { for(int i=0; i<=t; i++) d[i]=inf; memset(inq,0,sizeof(inq)); d[s]=0; inq[s]=1; p[s]=0; a[s]=inf; queue<int> Q; Q.push(s); while(!Q.empty()) { int u=Q.front(); Q.pop(); inq[u]--; for(int i=0; i<G[u].size(); i++) { edge &e=es[G[u][i]]; if(e.cap>e.flow && d[e.to]>d[u]+e.cost) { d[e.to]=d[u]+e.cost; p[e.to]=G[u][i]; a[e.to]=min(a[u],e.cap-e.flow); if(!inq[e.to]) { inq[e.to]++; Q.push(e.to); } } } } if(d[t]==inf) return false; flow+=a[t]; cost+=d[t]*a[t]; int u=t; while(u!=s) { es[p[u]].flow+=a[t]; es[p[u]^1].flow-=a[t]; u=es[p[u]].from; } return true; } int Maxflow(int s,int t) { int flow=0,cost=0; while(SPFA(s,t,flow,cost)) ; return cost; } }ans; int tmp,pos[N],from[N],to[N],val[N]; int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); scanf("%d",&_); while(_--){ memset(pos,0,sizeof(pos)); scanf("%d%d%d",&n,&k,&m); ans.init(m*2);tmp=0; for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); from[i]=x,to[i]=y,val[i]=z; pos[++tmp]=x,pos[++tmp]=y; } sort(pos+1,pos+tmp+1); int sz=unique(pos+1,pos+1+tmp)-pos-1; int st=0,ed=sz+1; ans.addedge(st,1,k,0);ans.addedge(sz,ed,k,0); for(int i=2;i<=sz;i++) ans.addedge(i-1,i,k,0); for(int i=1;i<=m;i++){ int x=lower_bound(pos+1,pos+sz+1,from[i])-pos,y=lower_bound(pos+1,pos+sz+1,to[i])-pos; if(x>y) swap(x,y); ans.addedge(x,y+1,1,-val[i]); } printf("%d\n",-ans.Maxflow(st,ed)); } return 0; }