社区讨论

菜鸡求助,不如暴力分qaq

P5331[SNOI2019] 通信参与者 5已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@mi7y5vx0
此快照首次捕获于
2025/11/21 05:32
4 个月前
此快照最后确认于
2025/11/21 05:32
4 个月前
查看原帖
一 脸 懵 逼
CPP
#include<bits/stdc++.h>
#define MAXN 100005
#define MAXM 100005
#define inf (long long)4340410370284600380
#define reg register
#define inl inline
#define int long long
using namespace std;
deque <int> q;
int cnt=1,fst[MAXN<<1],nxt[MAXM],to[MAXM],w[MAXM],cot[MAXM],cur[MAXN<<1];
int n,W,a[MAXN],t[MAXN],S,T,dis[MAXN<<1],mincost,tot,sum;
bool inq[MAXN<<1],vis[MAXN<<1];
void AddEdge(reg int u,reg int v,reg int c,reg int fl)
{
	to[++cnt]=v;
	nxt[cnt]=fst[u];
	fst[u]=cnt;
	w[cnt]=c;
	cot[cnt]=fl;
}
inl bool Spfa()
{
	memset(dis,60,sizeof(dis));
	memset(inq,0,sizeof(inq));
	q.push_front(T);
	dis[T]=0;
	inq[T]=1;
	while(!q.empty())
	{
		reg int u=q.front();
		q.pop_front();
		inq[u]=0;
		for(reg int i=fst[u];i;i=nxt[i])
		{
			reg int v=to[i];
			if(dis[v]>dis[u]-cot[i] && w[i^1])
			{
				dis[v]=dis[u]-cot[i];
				if(!inq[v])
				{
					if(!q.empty() && dis[v]<dis[q.front()]) q.push_front(v);
					else q.push_back(v);
					inq[v]=1;
				}
			}
		}
	}
	return dis[S]!=inf;
}
int Dfs(reg int u,reg int flow)
{
	vis[u]=1;
	if(u==T || !flow) return flow;
	reg int used=0;
	for(reg int i=cur[u];i;i=nxt[i])
	{
		cur[u]=i;
		reg int v=to[i];
		if(dis[v]==dis[u]-cot[i] && w[i] && !vis[v])
		{
			reg int fl=Dfs(v,min(flow,w[i]));
			if(fl)
			{
				used+=fl;
				flow-=fl;
				w[i]-=fl;
				w[i^1]+=fl;
				if(!flow) break;
			}
		}
	}
	return used;
}
inl void zkwMCMF()
{
	while(Spfa())
	{
		vis[T]=1;
		while(vis[T])
		{
			memcpy(cur,fst,sizeof(fst));
			memset(vis,0,sizeof(vis));
			reg int fl=Dfs(S,inf);
			mincost+=dis[S]*fl;
		}
	}
}
void Link(reg int l,reg int r)
{
	if(l==r) return;
	reg int mid=l+r>>1,tot=0;
	Link(l,mid);
	Link(mid+1,r);
	for(reg int i=l;i<=r;i++) t[++tot]=a[i];
	sort(t+1,t+tot+1);
	tot=unique(t+1,t+tot+1)-t-1;
	for(reg int i=1;i<tot;i++)
	{
		AddEdge(i+sum,i+sum+1,inf,t[i+1]-t[i]);
		AddEdge(i+sum+1,i+sum,0,t[i]-t[i+1]);
		AddEdge(i+sum+1,i+sum,inf,t[i+1]-t[i]);
		AddEdge(i+sum,i+sum+1,0,t[i]-t[i+1]);
	}
	for(reg int i=l;i<=r;i++)
	{
		reg int pos=lower_bound(t+1,t+tot+1,a[i])-t;
		if(i<=mid)
		{
			AddEdge(pos+sum,i+n,1,0);
			AddEdge(i+n,pos+sum,0,0);
		}
		else
		{
			AddEdge(i,pos+sum,1,0);
			AddEdge(pos+sum,i,1,0);
		}
	}
	sum+=tot;
}
signed main()
{
	scanf("%lld %lld",&n,&W);
	S=0;
	T=n*2+1;
	sum=n*2+1;
	for(reg int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(reg int i=1;i<=n;i++)
	{
		AddEdge(S,i,1,0);
		AddEdge(i,S,0,0);
		AddEdge(i,T,1,W);
		AddEdge(T,i,0,-W);
		AddEdge(i+n,T,1,0);
		AddEdge(T,i+n,0,0);
	}
	Link(1,n);
	zkwMCMF();
	printf("%lld\n",mincost);
	return 0;
}

回复

5 条回复,欢迎继续交流。

正在加载回复...