求助zkw费用流
查看原帖
求助zkw费用流
341373
Autofreeze楼主2021/2/22 15:12

RT,我的代码不知道为什么加 log\log 的底数会对时间有影响,而且是直接从 2s 变成了 40ms,求大佬解答。

屑代码(75分

#include<bits/stdc++.h>
#define N 501001
#define MAX 2001
#define re register
#define inf 1e9
#define eps 1e-12
using namespace std;
typedef int ll;
typedef double db;
inline void read(re ll &ret)
{
	ret=0;re char c=getchar();re bool pd=false;
	while(!isdigit(c)){pd|=c=='-';c=getchar();}
	while(isdigit(c)){ret=(ret<<1)+(ret<<3)+(c&15);c=getchar();}
	ret=pd?-ret:ret;
	return;
}
ll n,m,s,t,cnt=-1,head[N],p[MAX][MAX],xx;
db d[N];
ll vis[N];
deque<ll>q;
ll from[N],to[N],flow[N],nxt[N];
db dis[N];
inline void add(re ll x,re ll y,re ll z,re db w)
{
	from[++cnt]=x;
	to[cnt]=y;
	flow[cnt]=z;
	dis[cnt]=w;
	nxt[cnt]=head[x];
	head[x]=cnt;
	return;
}
inline bool spfa(re ll s,re ll t)
{
	for(re int i=s;i<=t;i++)
		d[i]=-inf,vis[i]=0;
	d[t]=0;
	vis[t]=1;
	q.push_back(t);
	while(!q.empty())
	{
		re ll ver=q.front();
		q.pop_front();
		vis[ver]=0;
		for(re int i=head[ver];i!=-1;i=nxt[i])
		{
			if(flow[i^1]&&d[to[i]]<d[ver]-dis[i])
			{
				d[to[i]]=d[ver]-dis[i];
				if(!vis[to[i]])
				{
					vis[to[i]]=1;
					if(!q.empty()&&d[to[i]]>d[q.front()])
						q.push_front(to[i]);
					else
						q.push_back(to[i]);
				}
			}
		}
	}
	return d[s]>-inf;
}
ll val;
inline ll dfs(re ll ver,re ll lim)
{
	if(ver==t)
	{
		vis[ver]=val;
		return lim;
	}
	re ll out=0;
	vis[ver]=val;
	for(re int i=head[ver];i!=-1&&lim;i=nxt[i])
	{
		if(flow[i]&&vis[to[i]]!=val&&fabs(d[ver]-d[to[i]]-dis[i])<eps)
		{
			re ll tmp=dfs(to[i],min(lim,flow[i]));
			out+=tmp;
			lim-=tmp;
			flow[i]-=tmp;
			flow[i^1]+=tmp;
		}
	}
	return out;
}
inline void solve(re ll s,re ll t)
{
	re ll ret=0;
	while(spfa(s,t))
	{
		vis[t]=val;
		while(vis[t]==val)
		{
			val++;
			ret+=dfs(s,inf);
		}
	}
	return;
}
bool ans[MAX][MAX];
signed main()
{
	memset(head,-1,sizeof(head));
	read(n);
	read(m);
	s=0,t=n+m+1;
	for(re int i=1;i<=n;i++)
		for(re int j=1;j<=m;j++)
		{
			read(p[i][j]);
			add(i,j+n,1,log(p[i][j]));
			add(j+n,i,0,-log(p[i][j]));	
		}
	for(re int i=1;i<=n;i++)
		read(xx),add(s,i,xx,0),add(i,s,0,0);
	for(re int i=1;i<=m;i++)
		read(xx),add(i+n,t,xx,0),add(t,i+n,0,0);
	solve(s,t);
	for(re int i=1;i<=n;i++)
	{
		for(re int j=head[i];~j;j=nxt[j])
		{
			if(to[j]>n&&flow[j^1])
				ans[i][to[j]-n]=true;
		}
	}
	for(re int i=1;i<=n;i++)
	{
		for(re int j=1;j<=m;j++)
		{
			if(ans[i][j])
				putchar('1');
			else
				putchar('0');
		}
		putchar('\n');
	}
		
	exit(0);
}
2021/2/22 15:12
加载中...