1. 程式人生 > >網絡流總結

網絡流總結

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

網絡流總結