您的位置:首页 > 理论基础 > 计算机网络

[网络流24题 #18]分配问题

2014-01-21 13:40 381 查看
这个题目写到了手残的境界,十分感动,不必多说。

首先是加反向边时下标没有反过来,然后是基于费用的最短(最长)路每次写成基于弧的容量……

最后就是临时数组开小了,导致开始评测只有11分,搞得我真是很无语。

看了wjk大神在很久很久以前的代码,发现他的增广是递归式的(在这一点上我比他有优势,非递归)

最后发现wjk大神代码没有用临时数组,着实把我震撼了,后来才发现他原来用正向边和反向边的关系直接还原容量。这个我的代码没有改过来,不过评测时还是比他快3ms,(*^__^*) ……

下面上我的代码(至于wjk大神的,点这里)#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define clean(x,y) memset(x,y,sizeof(x))
#define compare(CurP,AnoP,way) way? d[AnoP]<d[CurP]+a[i].cost:d[AnoP]>d[CurP]+a[i].cost
#define loop(i,u) for(i=p[T][0],u=p[T][1];i!=-1;i=p[u][0],u=p[u][1])
#define add(x) Q.push(x),v[x]=1
#define del(x) x=Q.front(),Q.pop(),v[x]=0
#define MaxN 110
using namespace std;
const int lim[2]={~0U>>2,-(~0U>>2)};
int n,tot,S,T; /*source & sink*/
int head[MaxN],d[MaxN],p[MaxN][2]; /*Augment Path*/
int temp[2*MaxN*MaxN]; /*Temp Cap*/
struct edge
{
int v,cap,cost,next;
edge(int x,int y,int c,int b):v(y),cap(c),cost(b)
{
next=head[x];
head[x]=tot++;
}
};
vector<edge> a;
bool v[MaxN]; /*If in Queue*/
inline void AddEdge(const int &x,const int &y,const int &cap,const int &cost)
{
a.push_back(edge(x,y,cap,cost));
a.push_back(edge(y,x,0,-cost));
}
inline void init()
{
int w;
cin>>n;
clean(head,-1);
for(int i=1;i<=n;i++)
for(int j=n+1;j<=2*n;j++)
scanf("%d",&w),
AddEdge(i,j,lim[0],w);
S=2*n+1,T=2*n+2;
for(int i=1;i<=n;i++)
AddEdge(S,i,1,0);
for(int j=n+1;j<S;j++)
AddEdge(j,T,1,0);
n=T;
}
inline bool spfa(bool cmp) /* cmp=0:shortest cmp=1:longest */
{
queue<int> Q;
for(int i=1;i<=T;i++)
d[i]=lim[cmp];
d[S]=0;
add(S);
clean(v,0);
clean(p,-1);
int x,y;
while(!Q.empty())
{
del(x);
for(int i=head[x];i!=-1;i=a[i].next)
{
y=a[i].v;
if(temp[i]>0&&(compare(x,y,cmp)))
{
d[y]=d[x]+a[i].cost;
p[y][0]=i,p[y][1]=x;
if(!v[y]) add(y);
}
}
}
return d[T]!=lim[cmp];
}
inline void work()
{
int cost,u,i,flow;
for(int way=0;way<2;way++)
{
cost=0;
for(i=0;i<tot;i++) temp[i]=a[i].cap;
while(spfa(way))
{
flow=lim[0];
loop(i,u)
if(flow>temp[i])
flow=temp[i];
loop(i,u)
{
temp[i]-=flow;
temp[i^1]+=flow;
}
cost+=d[T]*flow;
}
cout<<cost<<endl;
}
}
int main()
{
init();
work();
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  费用流 SPFA 网络流