请自动忽略掉 if(chkn) 里面的内容 那是我用来debug的
!!!注意 要 爆 int
我就直接全部开成long long 了 (#define long long int, signed main())
如图 边都是从左到右的单向边。
每个月 对应两个点
从 超源点到 每个月的生产点代表生产
从 每个月售卖点 到 超绘点 是为了 统计
不同月 的 生产点 到 售卖点 指的是 售卖过程
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;![在这里插入图片描述](https://img-blog.csdnimg.cn/20190714193441729.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMxODA1NTkx,size_16,color_FFFFFF,t_70)
#define int long long
const int maxn = 210;
const int id1 = 208;
const int id2 = 209;
const int INF = 2e9;
struct edge
{
int ss;
int ee;
int sp;
int ww;
edge(int ss1, int ee1, int sp1, int ww1)
{
ss = ss1;
ee = ee1;
sp = sp1;
ww = ww1;
}
};
vector< vector<int> > vv(maxn), vv_empty(maxn);
vector< edge > vee;
int n, m;
int aa[maxn], bb[maxn], cc[maxn], dd[maxn], ee[maxn];
int cnt[maxn], vis[maxn], dis[maxn], prv[maxn], msp[maxn];
bool chk1 = 0;
bool chk2 = 0;
bool chk3 = 0;
bool fre = 0;
void AddEdge(int ss, int ee, int sp, int ww)
{
vee.push_back(edge(ss, ee, sp, ww));
vee.push_back(edge(ee, ss, 0, -ww));
vv[ss].push_back(vee.size() - 2);
vv[ee].push_back(vee.size() - 1);
}
void initial()
{
vee.clear();
vv = vv_empty;
}
int spfa()
{
queue<int> que;
memset(vis, 0, sizeof(vis));
for(int i = 0;i < maxn;i++) dis[i] = INF;
que.push(id1);
vis[id1] = 1;
dis[id1] = 0;
msp[id1] = INF;
while(que.size())
{
int ss = que.front();
if(chk1) printf("spfa: ss=%lld minsp=%lld\n", ss, msp[ss]);
que.pop();
vis[ss] = 0;
for(int i = 0;i < vv[ss].size();i++)
{
int ii = vv[ss][i];
int ee = vee[ii].ee;
int ww = vee[ii].ww;
int sp = vee[ii].sp;
if(!sp || dis[ss] + ww >= dis[ee]) continue;
dis[ee] = dis[ss] + ww, prv[ee] = ii, msp[ee] = min(sp, msp[ss]);
if(vis[ee]) continue;
else que.push(ee), vis[ee] = 1;
}
}
if(dis[id2] >= 0)
{
if(chk1) printf("return 0!\n");
return 0;
}
int ss = id2;
int res = 0;
int minsp = msp[id2];
while(ss != id1)
{
int ii = prv[ss];
vee[ii].sp -= minsp;
vee[ii ^ 1].sp += minsp;
res += vee[ii].ww * minsp;
ss = vee[ii].ss;
}
if(chk1) printf("RES=%lld\n", res);
return res;
}
signed main()
{
int T;
int kase = 0;
if(fre) freopen("in.txt", "r", stdin), freopen("out.txt", "w", stdout);
scanf("%lld", &T);
while(T--)
{
initial();
int TmpR = 0;
int res = 0;
scanf("%lld%lld", &n, &m);
for(int ii = 1;ii <= n;ii++)
{
int a, b, c, d, e;
scanf("%lld%lld%lld%lld%lld", &a, &b, &c, &d, &e);
aa[ii] = a;
bb[ii] = b;
cc[ii] = c;
dd[ii] = d;
ee[ii] = e;
}
for(int ii = 1;ii <= n;ii++)
{
AddEdge(id1, ii, bb[ii], aa[ii]);
for(int i = 0;i <= ee[ii];i++)
{
if(ii + i > n) break;
AddEdge(ii, ii + n + i, INF, -cc[ii + i] + m * i);
}
AddEdge(ii + n, id2, dd[ii], 0);
}
while(TmpR = spfa()) res += TmpR;
printf("Case %lld: %lld\n", ++kase, -res);
}
return 0;
}