本来和job一样是一道水题,没有想到错误会出在循环的起始值上,这说明写代码时的智商还是有点低,应该多加训练,就是这样O__O"…
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#define clean(x,y) memset(x,y,sizeof(x))
#define add(x) Q.push(x),v[x]=1
#define del(x) x=Q.front(),Q.pop(),v[x]=0
#define cmp(CurP,AnoP,CmpWay) (CmpWay? d[AnoP]<d[CurP]+a[i].cost:d[AnoP]>d[CurP]+a[i].cost)
#define MaxN 110
#define INF ~0U>>2
using namespace std;
const int lim[2]={INF,-(INF)};
int head[MaxN],p[MaxN][2],d[MaxN];
bool v[MaxN];
int n,m,tot,S,T;
struct edge
{
int v,next,cap,cost;
edge(int v1,int v2,int c,int b):v(v2),cap(c),cost(b),next(head[v1])
{head[v1]=tot++;}
};
vector<edge> a;
inline void AddEdge(int x,int y,int cap,int cost)
{
a.push_back(edge(x,y,cap,cost));
a.push_back(edge(y,x,0,-cost));
}
inline void init()
{
int w;
clean(head,-1);
cin>>m>>n;
S=0,T=m+n+1;
for(int i=1;i<=m;i++)
scanf("%d",&w),
AddEdge(S,i,w,0);
for(int j=m+1;j<T;j++)
scanf("%d",&w),
AddEdge(j,T,w,0);
for(int i=1;i<=m;i++)
for(int j=m+1;j<T;j++)
scanf("%d",&w),
AddEdge(i,j,INF,w);
}
inline bool spfa(bool way)
{
int i,x,y;
queue<int> Q;
clean(p,-1);
clean(v,0);
for(i=1;i<=T;i++) d[i]=lim[way];
add(S),d[S]=0;
while(!Q.empty())
{
del(x);
for(i=head[x];i!=-1;i=a[i].next)
{
y=a[i].v;
if(a[i].cap>0&&cmp(x,y,way))
{
d[y]=d[x]+a[i].cost;
p[y][0]=i,p[y][1]=x;
if(!v[y]) add(y);
}
}
}
return d[T]!=lim[way];
}
inline void RefreshNetwork()
{
for(int i=0;i<tot;i+=2)
a[i].cap+=a[i^1].cap,
a[i^1].cap=0;
}
inline void work()
{
int i,u,cost=0,flow;
while(spfa(0))
{
flow=INF;
for(i=p[T][0],u=p[T][1];i!=-1;i=p[u][0],u=p[u][1])
if(flow>a[i].cap)
flow=a[i].cap;
for(i=p[T][0],u=p[T][1];i!=-1;i=p[u][0],u=p[u][1])
a[i].cap-=flow,
a[i^1].cap+=flow;
cost+=flow*d[T];
}
cout<<cost<<endl;
RefreshNetwork(),cost=0;
while(spfa(1))
{
flow=INF;
for(i=p[T][0],u=p[T][1];i!=-1;i=p[u][0],u=p[u][1])
if(flow>a[i].cap)
flow=a[i].cap;
for(i=p[T][0],u=p[T][1];i!=-1;i=p[u][0],u=p[u][1])
a[i].cap-=flow,
a[i^1].cap+=flow;
cost+=flow*d[T];
}
cout<<cost;
}
int main()
{
init();
work();
return 0;
}