简单的费用流建模 一个区间ab 从a到b连边 然后从源到汇一路串起来 源汇容量K
我们注意到图中的节点连接都是一路向右的,所以这k的流量经过所有节点最多1次,所以不会有节点被访问超过k次。
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define cl(x) memset(x,0,sizeof(x)) using namespace std; typedef long long ll; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=1005; struct edge{ int u,v,f,w; int next; }G[N<<1]; int head[N],inum=1; inline void add(int u,int v,int w,int f,int p){ G[p].u=u; G[p].v=v; G[p].w=w; G[p].f=f; G[p].next=head[u]; head[u]=p; } inline void link(int u,int v,int w,int f){ add(u,v,w,f,++inum); add(v,u,-w,0,++inum); } int S,T; int pre[N],dis[N],ins[N]; int Q[1000005],l,r; #define V G[p].v ll Maxcost; inline bool SPFA(){ for (int i=1;i<=T;i++) dis[i]=-1<<30,pre[i]=0,ins[i]=0; l=r=-1; dis[S]=0; Q[++r]=S; ins[S]=1; while (l!=r){ int u=Q[++l]; ins[u]=0; for (int p=head[u];p;p=G[p].next) if (G[p].f && dis[V]<dis[u]+G[p].w){ dis[V]=dis[u]+G[p].w; pre[V]=p; if (!ins[V]) Q[++r]=V,ins[V]=1; } } if (dis[T]<0) return 0; int minv=1<<30; for (int p=pre[T];p;p=pre[G[p].u]) minv=min(minv,G[p].f); Maxcost+=(ll)minv*dis[T]; for (int p=pre[T];p;p=pre[G[p].u]) G[p].f-=minv,G[p^1].f+=minv; return 1; } int sx[N],icnt; inline int Bin(int x){ return lower_bound(sx+1,sx+icnt+1,x)-sx; } int n,K; int us[N],vs[N],ws[N]; int main(){ int Q; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(Q); while (Q--){ icnt=0; read(n); read(K); for (int i=1;i<=n;i++) read(us[i]),read(vs[i]),read(ws[i]),sx[++icnt]=us[i],sx[++icnt]=vs[i]; sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1; S=icnt+1+1,T=icnt+1+2; for (int i=1;i<=n;i++) us[i]=Bin(us[i]),vs[i]=Bin(vs[i]),link(us[i],vs[i],ws[i],1); for (int i=1;i<=icnt;i++) link(i,i+1,0,1<<30); link(S,1,0,K); link(icnt+1,T,0,K); Maxcost=0; while (SPFA()); printf("%lld\n",Maxcost); cl(head); inum=1; } return 0; }