http://acm.hdu.edu.cn/showproblem.php?pid=6437
最大费用?先取相反数得最小再取相反数即最大。
最小费用最大流。将每部电影一分为二的拆开,左点连源点s,右点连汇点t,连的都是容量为INF、费用为0的边,左到右点自然连的是容量为1,费用-val的边;
再来一个到源点s的es,它到s连一条容量k(k个人)、费用0;
考虑到电影的时间冲突,O(
m
2
m^2
m2) for/for,同种电影连的边费用w,否则0
//187MS
#include <bits/stdc++.h>
#define ll long long
#define L(u) u<<1
#define R(u) u<<1|1
using namespace std;
const int MXN = 410;
const int MXM = 100000;
const int INF = 0x3f3f3f3f;
struct data {
int u,v,cap,flow,cost,nxt;
}g[MXM];
int head[MXN],tot,pre[MXN],dis[MXN];//Here tot start from 0. So head[] should be initialized to -1.
int Que[MXM],l,r;//for SPFA
bool vis[MXN];
void addEdge(int u,int v,int w,int c) {
g[tot]=(data){u,v,w,0,c,head[u]};
head[u]=tot++;
g[tot]=(data){v,u,0,0,-c,head[v]};
head[v]=tot++;
}
bool SPFA(int s,int t) {
memset(dis,INF,sizeof dis);
memset(vis,0,sizeof( vis));
memset(pre,-1,sizeof pre);
dis[s]=0;
vis[s]=true;
l=-1,r=0,Que[0]=s;
int u,v;
data e;
while (l<r) {
u = Que[++l];
vis[u]=false;
for (int i=head[u];~i;i=g[i].nxt) {
e=g[i];
if (dis[e.v]>dis[u]+e.cost&&e.cap>e.flow) {
dis[e.v]=dis[u]+e.cost;
pre[e.v]=i;
if (!vis[e.v]) {
vis[e.v]=true;
Que[++r]=e.v;
}
}
}
}
return pre[t]!=-1;
}
void MCMF(int s,int t,int &cost,int &flow) {
flow=cost=0;
int mini;
while (SPFA(s,t)) {
mini=INF;
for (int i=pre[t];~i;i=pre[g[i^1].v]) mini = min(mini,g[i].cap-g[i].flow);
for (int i=pre[t];~i;i=pre[g[i^1].v]) {
g[i].flow+=mini;
g[i^1].flow-=mini;
cost+=g[i].cost*mini;
}
flow += mini;
}
}
struct movie{
int s,e,val,op;
}d[201];
int T,n,m,k,u,v,w;
int ansFlow,ansCost,es,s,t;
int main() {
//freopen("../in","r",stdin);
scanf("%d",&T);
while (T--) {
tot=0;
memset(head,-1,sizeof head);
scanf("%d%d%d%d",&n,&m,&k,&w);
for (int i=1;i<=m;++i) scanf("%d%d%d%d",&d[i].s,&d[i].e,&d[i].val,&d[i].op);
es=0,s=1,t=m*2+2;
addEdge(es,s,k,0);//There are k person in all.
for (int i=1;i<=m;++i) {
addEdge(s,L(i),m,0);//m:INF
addEdge(L(i),R(i),1,-d[i].val);
addEdge(R(i),t,m,0);
}
for (int i=1;i<=m;++i)
for (int j=1;j<=m;++j)
if (i!=j&&d[i].e<=d[j].s) {
if (d[i].op==d[j].op) addEdge(R(i),L(j),m,w);//m:INF
else addEdge(R(i),L(j),m,0);
}
MCMF(es,t,ansCost,ansFlow);
printf("%d\n",-ansCost);
}
return 0;
}