1、这是一个无固定流量的最小费用流,费用负最小就是利润正最大,因此当费用增广到大于等于0,费用就开始增大,利润开始减小,因此当一次增广发现费用大于等于0就要退出了,没意识到这一点一直输出10
2、由于最终的利润会超int,我又又又忘记把中间量设置为long long一直在wa
3、建图的时候注意不要延迟到M月之后再卖
4、不要用太相似的变量名,尤其是不要用不符合自己习惯的!!!!!
//A
//中间量用了long Long
//不要把变量名写的太像,我把月份和每月费用写叉了,样例居然过了
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=250;
struct Edge
{
int from,to,cap,flow,cost;
Edge(){}
Edge(int f,int t,int c,int fl,int cs):from(f),to(t),cap(c),flow(fl),cost(cs){}
};
struct MCMF
{
int n,m,s,t;
int inq[MAXN];
int d[MAXN];
int p[MAXN];
int a[MAXN];
vector<Edge>edges;
vector<int> G[MAXN];
void init(int n) //n为结点个数
{
this->n=n;
edges.clear();
for(int i=0;i<MAXN;++i)
G[i].clear();
}
void AddEdge(int u,int v,int cap,int cost)
{
edges.push_back(Edge(u,v,cap,0,cost));
edges.push_back(Edge(v,u,0,0,-cost));
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
bool SPFA(int s,int t,int &flow,long long &cost)
{
memset(d,INF,sizeof(d));
memset(inq,0,sizeof(inq));
queue<int>q;
q.push(s);
d[s]=0; a[s]=INF; p[s]=0; inq[s]=1;
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=0;
for(int i=0;i<G[u].size();++i)
{
Edge &e=edges[G[u][i]];
if(e.cap>e.flow&&d[e.to]>d[u]+e.cost)
{
d[e.to]=d[u]+e.cost;
p[e.to]=G[u][i];
a[e.to]=min(a[u],e.cap-e.flow);
if(!inq[e.to])
{
q.push(e.to);
inq[e.to]=1;
}
}
}
}
if(d[t]==INF||d[t]>0) return false; //d[t]>0 亏本退出 最小成本>0
flow+=a[t];
cost+=(long long)a[t]*d[t]; //不加LL 会wa 的!!!
int u=t;
while(u!=s)
{
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
u=edges[p[u]].from;
}
return true;
}
long long MinCost(int s,int t)
{
int flow=0;
long long cost=0;
while(SPFA(s,t,flow,cost));
return cost;
}
}mc;
int main()
{
//freopen("a.txt","r",stdin);
int T;
scanf("%d",&T);
int kase=0;
while(T--)
{
kase++;
int m,I;
scanf("%d%d",&m,&I);
mc.init(2*m+2);
//如何记录最大到哪个月呢 //只考虑m个月,审题
// memset(m,0,sizeof(m));
int mi,n,p,s,e;
for(int i=1;i<=m;++i)
{
scanf("%d%d%d%d%d",&mi,&n,&p,&s,&e);
mc.AddEdge(0,i,n,mi);
for(int j=0;j<=e;++j)
{
if(i+j<=m) //
mc.AddEdge(i,m+i+j,n,I*j); //
}
mc.AddEdge(m+i,2*m+1,s,-p);
}
long long cost=mc.MinCost(0,2*m+1);
printf("Case %d: %lld\n",kase,-cost);
}
}