# Delight for a Cat

A cat is going on an adventure.
Each hour, the cat can be either sleeping or eating. The cat cannot be doing both actions at the same
hour, and the cat is doing exactly one of these actions for the whole hour.
For each of the next n hours, the amount of delight the cat is getting if it is sleeping or eating during
that hour is known. These amounts can be different for each hour.
An integer time period k is also known. Among every k consecutive hours, there should be at least
ms hours when the cat is sleeping, and at least me hours when the cat is eating. So, there are exactly
n − k + 1 segments of k hours for which this condition must be satisfied.
Find the maximum total amount of delight the cat can get during the next n hours.

1)对于所有点i，向i+k+1（如果大于T就置为T）连一条容量为1，权值为-w[i]的边

2)对于所有点i，向i+1连一条容量为k-ms-me，权值为0的边

3)从S向n+2连一条容量为k-ms的边，权值为0的边

4)从S向1 ~ k连一条容量为INF，权值为0的边

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define MAXN 2010
#define MAXM 3010
using namespace std;
const int INF = 0x3f3f3f3f;
struct edge
{
int u,v,c,nxt;
ll w;
}edg[MAXM<<1];
inline void addedg(int u,int v,int c,ll w)
{
edg[tot].u = u;
edg[tot].v = v;
edg[tot].c = c;
edg[tot].w = w;
}
inline void add(int u,int v,int c,int w)
{
}
int vis[MAXN],pre[MAXN],path[MAXN],N;
ll cost,d[MAXN];
//d用来存最短路,pre用来存路径,path用来存用了哪条边,cost用来保存最小费用
inline bool SPFA(int st,int ed)
{
memset(d,0x3f,sizeof(ll)*(N+1));
memset(pre,-1,sizeof(int)*(N+1));
memset(path,-1,sizeof(int)*(N+1));
memset(vis,0,sizeof(int)*(N+1));
queue<int> qu;
d[st] = 0;
vis[st] = 1;
qu.push(st);
while(!qu.empty())
{
int u = qu.front();
qu.pop();
vis[u] = 0;
for(int i = head[u];i != -1;i = edg[i].nxt)
{
int v = edg[i].v;
if(d[u] + edg[i].w < d[v] && edg[i].c > 0)
{
d[v] = d[u] + edg[i].w;
pre[v] = u;
path[v] = i;
if(!vis[v])
{
vis[v] = 1;
qu.push(v);
}
}
}
}
return pre[ed] != -1;
}
inline int minCostMaxFlow(int st,int ed)
{
int flow = 0;
while(SPFA(st,ed))
{
int minn = INF;
for(int i = ed;i != st;i = pre[i])
minn = min(minn,edg[path[i]].c);//求出新增加的流量
for(int i = ed;i != st;i = pre[i])
{
edg[path[i]].c -= minn;
edg[path[i]^1].c += minn;
}
//        if(d[ed] >= 0) //保证费用最小，去掉后保证流量最大
//            break;
flow += minn;
cost += minn * d[ed];
}
return flow;
}
inline void init()
{
tot = cost = 0;
}
int n,k,ms,me,id[MAXN];
ll s[MAXN],e[MAXN];
int main()
{
freopen("delight.in","r",stdin);
freopen("delight.out","w",stdout);
while(~scanf("%d%d%d%d",&n,&k,&ms,&me))
{
ll ans = 0;
for(int i = 1;i <= n;++i)
{
scanf("%lld",&s[i]);
ans += s[i];
}
int S = 0,T = n+1;
N = T+1;
init();
for(int i = 1;i <= n;++i)
scanf("%lld",&e[i]);
for(int i = 1;i <= n;++i)
{
id[i] = tot;
}
for(int i = 1;i <= k;++i)
minCostMaxFlow(S,T);
ans -= cost;
printf("%lld\n",ans);
for(int i = 1;i <= n;++i)
if(edg[id[i]].c == 0)
printf("E");
else
printf("S");
printf("\n");
}
return 0;
}


©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客