题意:
1)一天有n个小时,m个c菌的视频(一共有2中类型的视频,如果观看不同类型的视频将会扣除一个w(定值)的快乐值),k个人。
2)现在给出m个视频的s(开始时间),t(结束时间),w(看视频所能获得的快乐值),t(类型)。
3)没个视频只能最多由一个人观看。
4)求这群人最大的快乐值。
define:(from,to,cap,cost),源点为s,次源点为ss,汇点为t。
思路:
1) 因为是k个人,我们需要建立一个次源点来保证。(s,ss,k,0)
2)拆点,保证每段视频只有一个人观看
3)在对于每段视频,找到一段开始时间比他本身结束大的,就建边(i+m,j,inf,w),如果是同类型的就是0,不同类型的是-w。
4)因为求的是最大的快乐值,模板是取最小费用。所以添加一个符号就行(也就是为什么是-
w的原因)
#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define UINT unsigned LL
#define MAXN (100000+100)
#define lnn putchar('\n')
#define see putchar(' ')
using namespace std;
const LL maxn=1e5+7;
const LL MOD=1e9+7;
inline LL read()
{
LL X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
inline void write(LL x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const LL M=1000001;
const LL N=5500;
const LL inf=0x3f3f3f3f3f3f3f3f;
LL head[N],n,m,cnt;
struct node{
LL to,cap,money,next;
}edge[M];
struct MCMF{
LL len[N];
LL pre[N];
LL path[N];
bool vis[N];
void init()
{
memset(head,-1,sizeof head);
cnt=0;
}
void add(LL u,LL v,LL cap,LL money)
{
edge[cnt].to=v;
edge[cnt].cap=cap;
edge[cnt].next=head[u];
edge[cnt].money=money;
head[u]=cnt++;
edge[cnt].to=u;
edge[cnt].cap=0;
edge[cnt].next=head[v];
edge[cnt].money=-money;
head[v]=cnt++;
}
bool spfa(LL s,LL t)
{
memset(vis,false,sizeof vis);
memset(pre,-1,sizeof pre);
memset(path,-1,sizeof path);
memset(len,inf,sizeof len);
queue<LL> q;
q.push(s);
vis[s]=true;
len[s]=0;
while(!q.empty()){
LL u=q.front();
q.pop();
vis[u]=false;
for(LL i=head[u];i!=-1;i=edge[i].next){
LL v=edge[i].to;
if(len[v]>len[u]+edge[i].money && edge[i].cap>0){
len[v]=len[u]+edge[i].money;
pre[v]=u;
path[v]=i;
if(!vis[v]){
vis[v]=true;
q.push(v);
}
}
}
}
return len[t]!=inf;
}
LL MinCostMaxFlow(LL s,LL t)
{
LL sum=0;
while(spfa(s,t)){
LL mmin=inf;
for(LL i=t;i!=s && i!=-1;i=pre[i]){
mmin=min(mmin,edge[path[i]].cap);
}
for(LL i=t;i!=s && i!=-1;i=pre[i]){
edge[path[i]].cap-=mmin;
edge[path[i]^1].cap+=mmin;
}
sum+=mmin*(len[t]);
}
return sum;
}
};
LL xx[N],yy[N],zz[N],ww[N];
int main()
{
MCMF mcmf;
LL T;
for(scanf("%lld",&T);T--;){
mcmf.init();
LL n,m,k,w; scanf("%lld%lld%lld%lld",&n,&m,&k,&w);
LL S=2*m+1,T=2*m+3,SS=2*m+2;
mcmf.add(S,SS,k,0);
for(LL i=1;i<=m;i++) scanf("%lld%lld%lld%lld",&xx[i],&yy[i],&zz[i],&ww[i]);
for(LL i=1;i<=m;i++){
mcmf.add(i,i+m,1,-zz[i]);
mcmf.add(SS,i,inf,0);
mcmf.add(i+m,T,inf,0);
for(LL j=1;j<=m;j++){
if(i==j) continue;
if(yy[i]<=xx[j]){
if(ww[i]==ww[j]) mcmf.add(i+m,j,1,w);
else mcmf.add(i+m,j,1,0);
}
}
}
printf("%lld\n",-mcmf.MinCostMaxFlow(S,T));
}
return 0;
}