玄关,TLE50
查看原帖
玄关,TLE50
360025
zzyaba楼主2024/8/25 09:46

dinic

源点0,汇点n+n+1,第i天晚上i,第i天早上n+i

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define N 5000
#define M 25000
using namespace std;
bool vis[N];
int n,t,ans,cnt=1,sts[5],a[N],hd[N],dis[N],nxt[M],to[M],flow[M],cost[M];
queue<int>q;
void add(int u,int v,int f,int c){
	nxt[++cnt]=hd[u];
	hd[u]=cnt;
	to[cnt]=v;
	flow[cnt]=f;
	cost[cnt]=c;
	nxt[++cnt]=hd[v];
	hd[v]=cnt;
	to[cnt]=u;
	flow[cnt]=0;
	cost[cnt]=-c;
}
bool spfa(){
	memset(dis,inf,sizeof(dis));
	q.push(0);
	dis[0]=0;
	while(q.size()){
		t=q.front();
		q.pop();
		vis[t]=0;
		for(int i=hd[t];i;i=nxt[i]){
			if(flow[i]&&dis[to[i]]>dis[t]+cost[i]){
				dis[to[i]]=dis[t]+cost[i];
				if(!vis[to[i]]){
					vis[to[i]]=1;
					q.push(to[i]);
				}
			}
		}
	}
	return dis[n+n+1]!=inf;
}
int dfs(int cur=0,int remain=inf){
	if(cur==n+n+1||!remain){
		return remain;
	}
	vis[cur]=1;
	int ret=0,tmp;
	for(int i=hd[cur];i;i=nxt[i]){
		if(!vis[to[i]]&&dis[to[i]]==dis[cur]+cost[i]&&(tmp=dfs(to[i],min(flow[i],remain-ret)))){
			ans+=tmp*cost[i];
			ret+=tmp;
			flow[i]-=tmp;
			flow[i^1]+=tmp;
		}
	}
	vis[cur]=0;
	return ret;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=0;i<5;i++){
		cin>>sts[i];
	}
	for(int i=1;i<=n;i++){
		add(0,i,a[i],0);
		add(i+n,n+n+1,a[i],0);
		add(0,i+n,inf,sts[0]);
		if(i<n){
			add(i,i+1,inf,0);
		}
		if(i<=n-sts[1]){
			add(i,i+sts[1]+n,inf,sts[2]); 
		}
		if(i<=n-sts[3]){
			add(i,i+sts[3]+n,inf,sts[4]); 
		}
	}
	while(spfa()){ 
		dfs();
	}
	cout<<ans;
}
2024/8/25 09:46
加载中...