【CQOI2015】网络吞吐量

传送门:NKOJ3250

这是一道网络流水题(水题过不了系列=-=)。
题解:首先跑最短路(SPFA,dijkstra),然后枚举每一条边判断它是否是在最短路上,再用最短路上的边建好图跑一次最大流即可。

感谢@Mogician_Evian 帮我看丑代码。(模板题都要WA的我还是太菜了)

以下是我的丑代码:这里写图片描述

#include
#include
#include
#include
#define LL long long
const LL inf=1e18;
const int MAXN=505<<1;
const int MAXM=100005<<1;
using namespace std;
LL n,m,A[MAXM],B[MAXM],D[MAXM];
LL Last[MAXN],Next[MAXM],To[MAXM],pid;
LL Len[MAXM];
void Storepath(LL u,LL v,LL l){
    To[++pid]=v,Next[pid]=Last[u],Last[u]=pid,Len[pid]=l;
}
queueQ;
LL dis[MAXN][3];
bool ifin[MAXN];
void SPFA(LL St,LL fl){
    for(int i=2;i<=n;i++)dis[i][fl]=inf;
    dis[St][fl]=0,Q.push(St),ifin[St]=1;
    LL tmp;
    while(Q.size()){
        tmp=Q.front(),Q.pop(),ifin[tmp]=0;
        for(int i=Last[tmp];i;i=Next[i]){
            if(dis[To[i]][fl]>dis[tmp][fl]+Len[i]){
                dis[To[i]][fl]=dis[tmp][fl]+Len[i];
                if(!ifin[To[i]]){
                    Q.push(To[i]),ifin[To[i]]=1;
                }
            }
        }
    }
}
int CNT[MAXN],DIS[MAXN],START,END;
LL W[MAXN],WW,ANS,WWW[MAXN][MAXN];
LL SAP(LL U,LL FLOW){
    if(U==END)return FLOW;
    LL OUT=0,TMP;
    for(int I=1;I<=n;I++){
        if(DIS[I]+1!=DIS[U]||WWW[U][I]<=0)continue;
        OUT+=TMP=SAP(I,min(FLOW-OUT,WWW[U][I]));
        WWW[U][I]-=TMP,WWW[I][U]+=TMP;
        if(OUT==FLOW||DIS[START]>=END)return OUT;
    }
    if(!--CNT[DIS[U]])DIS[START]=END;
    CNT[++DIS[U]]++;
    return OUT;
}
LL ORZ[MAXN];
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%lld%lld%lld",&A[i],&B[i],&D[i]);
        Storepath(A[i],B[i],D[i]),Storepath(B[i],A[i],D[i]);
    }
    SPFA(1,1),SPFA(n,2);
    for(int i=1;i<=n;i++)scanf("%lld",&ORZ[i]);
    ORZ[1]=ORZ[n]=inf;
    for(int i=1;i<=m;i++)
        if(dis[A[i]][1]+D[i]+dis[B[i]][2]==dis[n][1]||dis[B[i]][1]+D[i]+dis[A[i]][2]==dis[n][1])
            WWW[A[i]][B[i]]=WWW[B[i]][A[i]]=min(ORZ[A[i]],ORZ[B[i]]);
    START=1,END=n;
    while(DIS[START]printf("%lld",ANS);
    return 0;
}

你可能感兴趣的:(网络流)