求助,帮忙卡个常
查看原帖
求助,帮忙卡个常
206024
Illusory_dimes楼主2021/2/27 15:36
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+10,M=2e4+10,K=(1<<11)+10,L=271;
const int INF=0x3f3f3f3f;
int n,m,k,q,s,t,cur[N],gap[N],dep[N],qt[N];
//cur[i]:当前弧优化,gap[i]:GAP优化 
int fst[N],tot=2,Fst[N][K>>1],Tot[K>>1];
int f[K],g[K],lim,Id[K],bit[K],U[N],I[N];
struct mdzz{int u,v,w;}id[24];
struct EDGE{int nxt,to,val;}e[M],E[M][L][2];
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
	return s*w;
}
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
inline void add(int u,int v,int w)
{
	e[tot]=(EDGE){fst[u],v,w},fst[u]=tot;++tot;
	e[tot]=(EDGE){fst[v],u,0},fst[v]=tot;++tot;
}
inline bool bfs()
{
	for(int i=1;i<=n;++i)
	cur[i]=fst[i],dep[i]=qt[i]=0;
	int hd=0,tl=1;
	dep[s]=1;qt[tl]=s;
	//这是从源点开始
	while(hd<tl)
	{
		int u=qt[++hd];
		for(int i=fst[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(!dep[v]&&e[i].val)
			{
				dep[v]=dep[u]+1;
				qt[++tl]=v;
			}
		}
	}
	return dep[t];
}
int dfs(int u,int lim)
{
	if(u==t)return lim;
	int ans=0,tmp;
	for(int i=cur[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		cur[u]=i;
		if(dep[v]==dep[u]+1&&e[i].val)
		{
			tmp=dfs(v,min(lim,e[i].val));
			e[i].val-=tmp,lim-=tmp;
			ans+=tmp,e[i^1].val+=tmp;
			if(!lim)break;
		}
	}
	return ans;
}
inline int dinic()
{
	int ans=0,tmp;
	while(bfs())
	{
		memcpy(cur,fst,sizeof(cur));
		while(tmp=dfs(s,INF))ans+=tmp;
	}
	return ans;
}
inline int BFS()
{
	for(int i=s;i<=t;++i)dep[i]=qt[i]=0;
//	int hd=0,tl=1;
	dep[s]=1;qt[1]=s;
	for(int hd=1,tl=1;hd<=tl;++hd)
	{
		int u=qt[hd];
		for(int i=fst[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(!dep[v]&&e[i].val)
			{
				dep[v]=dep[u]+1;
				U[v]=u,I[v]=i;
				qt[++tl]=v;
			}
			if(dep[t])break;
		}
		if(dep[t])break;
	}
	if(!dep[t])return 0;
	int ans=25,u=t;
	while(u!=s)ans=min(ans,e[I[u]].val),u=U[u];
	u=t;
	while(u!=s)e[I[u]].val-=ans,e[I[u]^1].val+=ans,u=U[u];
	return ans;
}
inline int FF()
{
	int ans=0,tmp;
	while(tmp=BFS())ans+=tmp;
	return ans;
}
int main()
{
	n=read(),m=read(),k=read(),q=read();
	lim=(1<<k)-1,s=1,t=n;
	for(int i=1;i<=k;++i)
	{
		id[i].u=read();
		id[i].v=read();
		id[i].w=read();
	}
	for(int i=k+1;i<=m;++i)
	{
		int u=read(),v=read(),w=read();
		add(u,v,w);
	}
	f[0]=dinic();
	Tot[0]=tot;
	for(int i=2;i<tot;++i)E[i][0][0]=e[i];
	for(int i=1;i<=n;++i)Fst[i][0]=fst[i];
	srand(time(0));
	for(int kkk=1;kkk<=k;++kkk)
	{
		int sum=0;
		for(int i=1;i<=lim;++i)
		{
			if(__builtin_popcountll(i)!=kkk)continue;
			Id[i]=++sum;
			for(int j=1;j<=k;++j)if((1<<(j-1))&i)bit[i]=max(bit[i],j-1);
			int Is=i^(1<<bit[i]);
			tot=Tot[Is];
			for(int j=2;j<tot;++j)e[j]=E[j][Id[Is]][(kkk&1)^1];
			for(int j=1;j<=n;++j)fst[j]=Fst[j][Is];
			add(id[bit[i]+1].u,id[bit[i]+1].v,25);
			f[i]=FF()+f[Is];
			Tot[i]=tot;
			for(int j=2;j<tot;++j)E[j][sum][kkk&1]=e[j];
			for(int j=1;j<=n;++j)Fst[j][i]=fst[j];
		}
	}
	while(q--)
	{
		for(int i=1;i<=k;++i)id[i].w=read();
		g[0]=0;
		int ans=INF;
		for(int i=1;i<=lim;++i)g[i]=g[i^(1<<bit[i])]+id[bit[i]+1].w;
		for(int i=0;i<=lim;++i)ans=min(ans,f[i]+g[i^lim]);
		printf("%d\n",ans);
	}
	return 0;
}
2021/2/27 15:36
加载中...