codevs1914 运输问题
题目描述 Description
输入描述 Input Description
输出描述 Output Description
样例输入 Sample Input
样例输出 Sample Output
啊啊啊啊啊啊啊啊
又是上次的错误
调了一个多小时
感谢某位大佬(哭唧唧。。。)
题目本身其实并不难
只是要记得跑最短路时dis数组初始化为inf
跑最长路时dis数组初始化为-inf!dis数组初始化为-inf!dis数组初始化为-inf!
当没有负权边时可为-1,但是因为费用流反向弧费用为原流的相反数
所以原来为正数的边权变为了负数
所以dis数组初始化为-inf!
每次都是因为仅初始为-1而调很久
所以保险起见都初始为-inf吧
代码写得略丑
见谅见谅
#include<cstdio>
#include<cstring>
#include<iostream>
const int inf=0x3f3f3f3f,N=50000;
struct node
{
int to,next,v,c,from;
}e[1000000],f[1000000];
int first[N],dis[N],qu[N],bo[N],from[N],first2[N];
int cnt=1,s,t,ans=0;
void insert(int u,int v,int q,int c)
{
e[++cnt].to=v;e[cnt].from=u;e[cnt].next=first[u];first[u]=cnt;e[cnt].v=q;e[cnt].c=c;
e[++cnt].to=u;e[cnt].from=v;e[cnt].next=first[v];first[v]=cnt;e[cnt].v=0;e[cnt].c=-c;
cnt-=2;
f[++cnt].to=v;f[cnt].from=u;f[cnt].next=first2[u];first2[u]=cnt;f[cnt].v=q;f[cnt].c=c;
f[++cnt].to=u;f[cnt].from=v;f[cnt].next=first2[v];first2[v]=cnt;f[cnt].v=0;f[cnt].c=-c;
}
bool spfa()
{
memset(dis,inf,4*(t+5));
int i=1,j=2;
qu[1]=s;bo[s]=1;dis[s]=0;
while(i!=j)
{
int r=qu[i++];bo[r]=0;if(i==N) i=0;
for(int k=first[r];k;k=e[k].next)
{
if(e[k].v>0&&dis[e[k].to]>dis[r]+e[k].c)
{
dis[e[k].to]=dis[r]+e[k].c;
from[e[k].to]=k;
if(!bo[e[k].to])
{
if(dis[e[k].to]<dis[i])
{
i--;if(i<0) i=N-1;
qu[i]=e[k].to;
}
else qu[j++]=e[k].to;if(j==N)j=0;
bo[e[k].to]=1;
}
}
}
}
if(dis[t]==inf) return 0;
return 1;
}
bool spfa2()
{
for(int i=0;i<=t;i++) dis[i]=-inf;
int i=1,j=2;
qu[1]=s;bo[s]=1;dis[s]=0;
while(i!=j)
{
int r=qu[i++];bo[r]=0;if(i==N) i=0;
for(int k=first2[r];k;k=f[k].next)
{
if(f[k].v>0&&dis[f[k].to]<dis[r]+f[k].c)
{
dis[f[k].to]=dis[r]+f[k].c;
from[f[k].to]=k;
if(!bo[f[k].to])
{
if(dis[f[k].to]>dis[i])
{
i--;if(i<0) i=N-1;
qu[i]=f[k].to;
}
else qu[j++]=f[k].to;if(j==N)j=0;
bo[f[k].to]=1;
}
}
}
}
if(dis[t]==-inf) return 0;
return 1;
}
void fa()
{
int min=inf;
for(int k=from[t];k;k=from[e[k].from])
min=min<e[k].v?min:e[k].v;
for(int k=from[t];k;k=from[e[k].from])
ans+=min*e[k].c,e[k].v-=min,e[k^1].v+=min;
}
void fa2()
{
int min=inf;
for(int k=from[t];k;k=from[f[k].from])
min=min<f[k].v?min:f[k].v;
for(int k=from[t];k;k=from[f[k].from])
ans+=min*f[k].c,f[k].v-=min,f[k^1].v+=min;
}
int main()
{
int m,n,p;
scanf("%d %d",&m,&n);
s=0,t=n+m+1;
for(int i=1;i<=m;i++)
scanf("%d",&p),insert(s,i,p,0);
for(int i=1;i<=n;i++)
scanf("%d",&p),insert(m+i,t,p,0);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&p),insert(i,m+j,inf,p);
while(spfa()) fa();
printf("%d\n",ans);
ans=0;
while(spfa2()) fa2();
printf("%d\n",ans);
return 0;
}