網絡流總結
阿新 • • 發佈:2018-01-04
spf inf ont down 總結 -c com queue clas
網絡流專題
Part1 一些代碼
(一)初始處理
1.最大流加邊
struct Edge{int to,nxt,w;}e[SZ]; // w:流量
int Ecnt=2,Ehead[SZ];
il void Eadd(int u,int v)
{
e[Ecnt]=(Edge){v,Ehead[u],1};
Ehead[u]=Ecnt++;
e[Ecnt]=(Edge){u,Ehead[v],0};
Ehead[v]=Ecnt++;
}
2.費用流加邊
struct Edge{int to,nxt,w,c;}e[SZ]; //w:流量,c:費用
int Ehead[SZ],pv[SZ],pe[SZ],Ecnt=2 ;
il void Eadd(int u,int v,int w,int cost)
{
e[Ecnt]=(Edge){v,Ehead[u],w,cost};
Ehead[u]=Ecnt++;
e[Ecnt]=(Edge){u,Ehead[v],0,-cost};
Ehead[v]=Ecnt++;
}
// pv[i] : spfa時使得i點dis值松弛的節點
//(最短路的上一節點)
//pe[i] : i與pv[i]連接的邊
3.註意事項
對於原點和匯點 s = 0,t=n+2
Ecnt(邊的起始編號)=2(一定不能是1)
(二)板子
1.最大流
int lev[SZ];
il bool bfs()
{
rg u,v;queue <int> Q;
memset(lev,-1,sizeof(lev));
lev[s]=1,Q.push(s);
while(!Q.empty())
{
u=Q.front(),Q.pop();
for(rg i=Ehead[u];i;i=e[i].nxt)
{
v=e[i].to;
if(e[i].w>0&&lev[v]<0)
{
lev[v]=lev[u]+1 ;
Q.push(v);
}
}
}
if(lev[t]>0) return 1;
return 0;
}
int cur[SZ],Ans;
int dfs(int u,int f)
{
if(u==t||f==0) return f;
for(int &i=cur[u];i;i=e[i].nxt)
{
rg di=0,v=e[i].to;
if((lev[v]==lev[u]+1)&&(e[i].w>0))
if(di=dfs(v,min(f,e[i].w)))
{
e[i].w-=di,e[i^1].w+=di;
return di;
}
}
return 0;
}
il void maxflow()
{
rg di=0;
while(bfs())
{
for(rg i=s;i<=t;++i) cur[i]=Ehead[i];
while((di=dfs(s,INF))&&(Ans+=di));
}
printf("%d",Ans);
}
2.費用流
ll dis[SZ];
int vis[SZ];
queue <int> Q;
bool spfa()
{
memset(dis,63,sizeof(dis));
dis[s]=0; Q.push(s);
while(!Q.empty())
{
rg u=Q.front();
Q.pop();
for(rg i=Ehead[u];i;i=e[i].nxt)
{
rg v=e[i].to;
if((e[i].w)&&(dis[v]>dis[u]+e[i].c))
{
dis[v]=dis[u]+e[i].c;
pe[v]=i;
pv[v]=u;
if(!vis[v])
{
vis[v]=1;
Q.push(v);
}
}
}
vis[u]=0;
}
return dis[t]<dis[0];
}
il void costflow()
{
ll Ans=0;
while(spfa())
{
rg di=INF;
for(rg i=t;i!=s;i=pv[i])
di=min(di,e[pe[i]].w);
for(rg i=t;i!=s;i=pv[i])
{
e[pe[i]].w-=di;
e[pe[i]^1].w+=di;
Ans+=1ll*di*e[pe[i]].c;
}
}
printf("%lld",Ans);
}
Part2 一些題目
(一) 最長k可重區間集問題
http://www.cnblogs.com/tply/p/8185899.html
網絡流總結