简单的费用流建模 一个区间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;
}
本文介绍了一种使用费用流解决区间问题的方法,通过构建特定的图模型来求解最大费用最小流问题。该方法适用于路径上每个节点仅被访问一次的情况,并提供了完整的代码实现。

1713

被折叠的 条评论
为什么被折叠?



