RT,我的代码不知道为什么加 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);
}