这个题非常的好,真的......我半颓半打,打了一下午最后还是去看了题解,,,,
这个题对限制条件的转换非常的好
先贴代码

1 #include<bits/stdc++.h>
2 using namespace std;
3
4 long long tot=-1,sum=0,h[10005],flow[10005],g[10005],ans=0,dis[10005],ans2=0,inf=999999;
5 bool vis[10005];
6 struct node{
7 long long from,to,next,rest,cost;
8 }e[10000005];
9
10 void add(long long x,long long y,long long z,long long hg){
11 tot++;
12 e[tot].next=h[x];
13 h[x]=tot;
14 e[tot].cost=hg;
15 e[tot].from=x;
16 e[tot].to=y;
17 e[tot].rest=z;
18 }
19
20 int bfs(long long s,long long t){
21 queue<int>q;
22 q.push(s);dis[s]=0;vis[s]=true;
23 while(!q.empty()){
24 long long u=q.front();q.pop();vis[u]=false;
25 for(int i=h[u];i!=(-1);i=e[i].next){
26 if(e[i].rest>0&&dis[e[i].to]>dis[u]+e[i].cost){
27 flow[e[i].to]=min(flow[u],e[i].rest);
28 dis[e[i].to]=dis[u]+e[i].cost;
29 g[e[i].to]=i;
30 if(vis[e[i].to]==false)q.push(e[i].to),vis[e[i].to]=true;
31 }
32 }
33 }
34 }
35
36 int EK(long long s,long long t){
37 while(1){
38 memset(flow,0x7f,sizeof(flow));
39 memset(dis,0x7f,sizeof(dis));
40 memset(g,-1,sizeof(g));
41 memset(vis,false,sizeof(vis));
42 bfs(s,t);
43 if(g[t]!=(-1)){
44 ans+=flow[t];ans2+=dis[t]*flow[t];
45 for(int p=t;p!=s;p=e[g[p]].from){
46 e[g[p]].rest-=flow[t];
47 e[g[p]^1].rest+=flow[t];
48 }
49 }
50 else break;
51 }
52 }
53
54 int n,P,m,f,N,S,r;
55
56 int main(){
57 memset(h,-1,sizeof(h));
58 cin>>n>>P>>m>>f>>N>>S;
59 for(int i=1;i<=n;i++){
60 cin>>r;
61 add(0,i,r,0);
62 add(i,0,0,0);
63 add(i+n,2*n+1,r,0);
64 add(2*n+1,i+n,0,0);
65 add(0,i+n,inf,P);
66 add(i+n,0,0,-P);
67 if(i+m<=n)add(i,i+m+n,inf,f),add(i+m+n,i,0,-f);
68 if(i+N<=n)add(i,i+N+n,inf,S),add(i+N+n,i,0,-S);
69 if(i<n)add(i,i+1,inf,0),add(i+1,i,0,0);
70 }
71 EK(0,2*n+1);
72 cout<<ans2<<endl;
73 }
我原本做这个题的时候,本来是这么想的
1.把节点分为用了和没用,俩俩连边
2.对于买,直接现在1号节点买好(因为后面什么时候买可以),就把源点连1号,同理汇点连n号用过的...
3.对于洗,就把用了的连多少天之后.....
4.然后在上面跑费用流就好了....
5.没用的之间俩俩连边....
但是错了.....
分析了一下,错的原因可能是因为求费用流的同时,通过先前节点走到哪里,比从源点直接到那个点的值大得多.....
那我又想了一下,直接处理一下洗衣服的边权不就可以了嘛.....因为对于洗衣服,相当于少付了这么多
但这东西就很怪.....
想不懂为什么wa了.....
可能是因为下面那条边,就是原本买多了的新衣服有路给过去了.......然后又因为求的是最大流.....
诶,那我把买多了的新衣服去掉,只有剩下的旧衣服会怎么样??,,图就不连通了
....
立个flag,谁用我上面的方法做出来我请你吃饭
好吧,向正解低头
嘛,正解用到了一个引理,就是每天一定能得到要求的衣服,只是途径不同,,,,,
那很好办了.
直接建立两种节点,有和没有用过的.....
然后对于用过的可以根据洗衣服的规则到这么多天的没有用过的....
然后买也可以解决,没用过的可以由买回来转移得到,于是可以把没用过与(与用掉的相连的源点粘接,代表经过买的连接)...
我在说什么....
嘛真的不推荐你们看这篇题解,太垃圾了....
反正啦,(绯红华尔兹好好听)
反正从这题得出了几个经验
1,不要边颓边学
2.要大力猜想题目条件,不能被局限在原有知识里
3.显然的东西就要大力去用
4.不要抄模板,多打一下多好
.
.
.
来源:https://www.cnblogs.com/shatianming/p/12222836.html
