/* 都说这题是构图很巧的好题~我也赞一个吧,虽然我没有想到。 说说我的思考过程吧。 做这题是因为这题在网络流的分类里面,自然一开始就想构图了~ (1)能作为结点的东西的只有两个,区间和端点,区间没什么道理,以端点做结点的话,离散化是要的; (2)k限制流量用,段的权值与流量没什么关系,是一种费用性的东西,所以是费用流; (3)考虑到区间包含连续的点,我画了一个S->1->2->...->T的线图(流量限制为k,费用暂时为0),并尝试对区间(a,b)(权值为w)加边add(S,a,w,1)和add(b,T,w,1),但又捣乱了流量关系,于是继续凌乱中~ 在哪个路口乱了咧?没理清楚的流量关系~差一点了! 建图改成代码中的那样后,即add(S,1,0,k),add(cnt,T,0,k),add(i,i+1,0,k),add(a,b,-w,1),a到b的流量一旦形成,a和b之间的点因为在a点之后,流量自然会超限,b之后的点流量也不会受影响,太可爱了!如果这个完整的思考过程属于我就爽了,ok,不写了,老友记ing。 */ #include <cstdio> #include <cstring> #include <stack> #include <queue> #include <iostream> using namespace std; const int NN=500; const int MM=10000; const int INF=0x3fffffff; struct node{ int a,b,w; }p[NN]; int S,T,NV,en,head[NN]; struct Edge{ int u,v,f,c,next; }e[MM]; void add(int u,int v,int c,int f) { e[en].u=u; e[en].v=v; e[en].c=c; e[en].f=f; e[en].next=head[u]; head[u]=en++; e[en].u=v; e[en].v=u; e[en].c=-c; e[en].f=0; e[en].next=head[v]; head[v]=en++; } int dis[NN],fa[NN]; bool vis[NN]; bool spfa() { for (int i=0; i<NV; i++) dis[i]=INF; dis[S]=0; fa[S]=-1; stack<int> q; q.push(S); while (!q.empty()) { int u=q.top(); q.pop(); vis[u]=false; for (int i=head[u]; i!=-1; i=e[i].next) { int v=e[i].v; if (e[i].f && dis[v]>dis[u]+e[i].c) { dis[v]=dis[u]+e[i].c; fa[v]=i; if (!vis[v]) { vis[v]=true; q.push(v); } } } } if (dis[T]!=INF) return true; else return false; } int mcmf() { int max_flow=0; int min_cost=0; while (spfa()){ int flow=INF; int u,v; for (v=T; fa[v]!=-1; v=u){ u=e[fa[v]].u; if (flow>e[fa[v]].f) flow=e[fa[v]].f; } for (v=T; fa[v]!=-1; v=u){ u=e[fa[v]].u; e[fa[v]].f-=flow; e[fa[v]^1].f+=flow; } max_flow+=flow; min_cost+=dis[T]; } return min_cost; } int hash[100005]; int main() { int cas,n,k,a,b,c; scanf("%d",&cas); while (cas--) { memset(hash,0,sizeof(hash)); scanf("%d%d",&n,&k); for (int i=0; i<n; i++) { scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].w); hash[p[i].a]=hash[p[i].b]=1; } int cnt=0; for (int i=1; i<=100000; i++) if (hash[i]) hash[i]=++cnt; S=0; T=cnt+1; NV=T+1; en=0; for (int i=0; i<NV; i++) head[i]=-1; for (int i=0; i<=cnt; i++) add(i,i+1,0,k); for (int i=0; i<n; i++) add(hash[p[i].a],hash[p[i].b],-p[i].w,1); printf("%d\n",-mcmf()); } return 0; }