An automobile factory has a car production line. Now the market is oversupply and the production line is often shut down. To make full use of resources, the manager divides the entire production line into NN parts (1...N)(1...N). Some continuous parts can produce sub-products. And each of sub-products has their own value. The manager will use spare time to produce sub-products to make money. Because of the limited spare time, each part of the production line could only work at most KK times. And Because of the limited materials, each of the sub-products could be produced only once. The manager wants to know the maximum value could he make by produce sub-products.
Input
The first line of input is TT, the number of test case.
The first line of each test case contains three integers, N, KN,K and MM. (MM is the number of different sub-product).
The next MM lines each contain three integers A_i, B_i, W_iAi,Bi,Wi describing a sub-product. The sub-product has value W_iWi. Only A_iAi to B_iBi parts work simultaneously will the sub-product be produced (include A_iAi to B_iBi).
1 \le T \le 1001≤T≤100
1 \le K \le M \le 2001≤K≤M≤200
1 \le N \le 10^51≤N≤105
1 \le A_i \le B_i \le N1≤Ai≤Bi≤N
1 \le W_i \le 10^51≤Wi≤105
Output
For each test case output the maximum value in a separate line.
样例输入复制
4 10 1 3 1 2 2 2 3 4 3 4 8 10 1 3 1 3 2 2 3 4 3 4 8 100000 1 3 1 100000 100000 1 2 3 100 200 300 100000 2 3 1 100000 100000 1 150 301 100 200 300
样例输出复制
10 8 100000 100301
题目来源
题意:生产产品有利润,但是需要时间,现在有K条生产线,问最大利润多少
解题思路:网络流24题原题 https://blog.csdn.net/icefox_zhx/article/details/78780575
建立源点S和汇点T,S向1点连接流量为k,边权为0的边,然后每个点向下一个点连接流量为无穷大,费用为0的边。对于每个线段,线段左端点向右端点连接流量为1,边权为线段长的边。最后的一个端点向T连接流量为k,费用为0的边,跑最大费用最大流即可。
要离散化。
#include <iostream>
#include <string.h>
#include <math.h>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <queue>
using namespace std;
const int MAXN = 40010;
const int INF = 0x3f3f3f3f;
typedef long long ll;
inline void scan_d(int &ret)
{
char c;
ret = 0;
while ((c = getchar()) < '0' || c > '9');
while (c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0'), c = getchar();
}
}
void Out(int a)
{ // 输出外挂
if (a < 0)
{
putchar('-');
a = -a;
}
if (a >= 10)
{
Out(a / 10);
}
putchar(a % 10 + '0');
}
struct edge
{
int u, v, cap, cost, next;
} e[3 * MAXN];
int edge_num;
int head[500];
void insert_edge(int u, int v, int cap, int cost)
{
e[edge_num].u = u;
e[edge_num].v = v;
e[edge_num].cap = cap;
e[edge_num].cost = cost;
e[edge_num].next = head[u];
head[u] = edge_num++;
//反向边 k^1即可求出反向边
e[edge_num].u = v;
e[edge_num].v = u;
e[edge_num].cap = 0; //注意这里
e[edge_num].cost = -cost; //注意这里
e[edge_num].next = head[v];
head[v] = edge_num++;
}
int dis[500];
int pre[500];
bool vis[500];
bool spfa(int s, int t)
{
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
dis[s] = 0;
vis[s] = 1;
queue<int> que;
que.push(s);
while (!que.empty())
{
int tp = que.front();
que.pop();
vis[tp] = 0;
for (int i = head[tp]; ~i; i = e[i].next)
{
int v = e[i].v;
int cost = e[i].cost;
if (e[i].cap && dis[v] > dis[tp] + cost)
{
dis[v] = dis[tp] + cost;
pre[v] = i;
if (!vis[v])
{
vis[v] = 1;
que.push(v);
}
}
}
}
if (dis[t] == INF)
return false;
return true;
}
pair<int, int> MCMF(int s, int t)
{
int maxflow = 0;
int mincost = 0;
int minc;
while (spfa(s, t))
{
minc = INF;
int cost = 0;
for (int i = pre[t]; ~i; i = pre[e[i].u])
minc = min(minc, e[i].cap);
for (int i = pre[t]; ~i; i = pre[e[i].u])
{
e[i].cap -= minc;
e[i ^ 1].cap += minc;
cost += minc * e[i].cost; //flow*unit cost=total cost
}
mincost += cost;
maxflow += minc;
}
return make_pair(mincost, maxflow);
}
int tot = 0;
int in[500];
int out[500];
int S, SK, T;
struct node{
int b,e,w;
}p[500];
vector<int> num;
int main()
{
int TT;
scan_d(TT);
while (TT--)
{
num.clear();
edge_num = 0;
memset(head, -1, sizeof(head));
tot = 0;
int N, M, K;
scan_d(N);
scan_d(K);
scan_d(M);
for (int i = 1; i <= M; i++){
scan_d(p[i].b);
scan_d(p[i].e);
scan_d(p[i].w);
p[i].e++;//左闭右开区间
num.push_back(p[i].b);
num.push_back(p[i].e);
}
sort(num.begin(),num.end());
int cnt=unique(num.begin(),num.end())-num.begin();//离散化
int S=++tot;
int T=++tot;
for(int i=0;i<cnt;i++){
in[i]=++tot;
}
insert_edge(S,in[0],K,0);
for(int i=0;i<cnt-1;i++)
insert_edge(in[i],in[i+1],INF,0);
for (int i = 1; i <= M; i++){
p[i].b=lower_bound(num.begin(),num.begin()+cnt,p[i].b)-num.begin();
p[i].e=lower_bound(num.begin(),num.begin()+cnt,p[i].e)-num.begin();
insert_edge(in[p[i].b],in[p[i].e],1,-p[i].w);
}
insert_edge(in[cnt-1],T,K,0);
Out(-MCMF(S, T).first);
puts("");
}
return 0;
}