2019杭电多校1005 Path 最短路+最大流(最小割)

现在假设受众已有 求图的所有最短路径 的前置知识

推荐阅读:白书P209 看懂最大流&最小割

今天没时间重构代码了。。。

就随便注释一下

题目呢是签到题

意思是给一个有向图

一个人要从1点走到n点

我们要阻碍他走最短路

而你堵塞一条边的代价就是这条边的长度

问最小代价

要是看懂了最小割
就知道这题几乎就是板子题

先用优先队列优化最短路,求所有最短路径的所有边
题解的方法可以学一手

采用的方法是先更新好所有点的最短距离 (题中的sp数组)
然后遍历所有边
接着如果说两个点的最短距离之差刚好是边的长度
那么这条边就是在最短路上

就是题解那个蜜汁公式的意思

for(int pos=1;pos<=n;++pos)
    for(auto &e : D::G[pos])
        if(sp[e.to]-sp[pos]==e.v)
            I::AddEdge(pos,e.to,e.v);

上图的下面的for等价于

for(int i=0;i<D::G[pos].size();i++){
    D::Edge e=D::G[pos][i];
}

学一手auto自适应类型

然后用最大流求答案。。。。

似乎就没了

#include 

template 
bool Reduce(T &a,T const &b) {
    return a>b?a=b,1:0;
}

const int XN=1e4+11;
const int INF=2e9;
const long long oo=1e18;

int n;
long long sp[XN];

namespace D {
    struct Edge {
        int to,v;
    };

    std::vector G[XN];
    //优先队列优化
    void Run() {
        static bool ud[XN];
        std::priority_queue,std::vector >,std::greater > > Q;//小根堆
        std::fill(sp+1,sp+1+n,oo);
        std::fill(ud+1,ud+1+n,0);
        sp[1]=0;
        Q.push(std::make_pair(0,1));
        while(!Q.empty()) {
            int pos=Q.top().second;Q.pop();
            if(ud[pos])
                continue;
            ud[pos]=1;
            for(auto int & e : G[pos]) {
                int u=e.to;
                if(Reduce(sp[u],sp[pos]+e.v))
                    Q.push(std::make_pair(sp[u],u));
            }
        }
    }
}

namespace I {
    //最大流求解
    struct Edge {
        int to,cap,v;
        Edge *rev,*pre;
    }*G[XN],*preArc[XN];

    void AddEdge(int x,int y,int c) {
        G[x]=new Edge{y,c,0,NULL,G[x]};
        G[y]=new Edge{x,0,0,G[x],G[y]};
        G[x]->rev=G[y];
    }

    int Aug() {
        int d=INF;
        for(int pos=n;preArc[pos];pos=preArc[pos]->rev->to)
            Reduce(d,preArc[pos]->cap-preArc[pos]->v);
        for(int pos=n;preArc[pos];pos=preArc[pos]->rev->to) {
            preArc[pos]->v+=d;
            preArc[pos]->rev->v-=d;
        }
        return d;
    }

    long long Run() {
        static int num[XN],d[XN];
        static Edge *cArc[XN];
        std::fill(num+1,num+n,0);
        std::fill(d+1,d+1+n,0);
        std::copy(G+1,G+1+n,cArc+1);
        num[0]=n;preArc[1]=0;
        long long flow=0;
        for(int pos=1;d[1]<n;) {
            if(pos==n) {
                flow+=Aug();
                pos=1;
            }
            bool adv=0;
            for(Edge *&e=cArc[pos];e;e=e->pre) {
                int u=e->to;
                if(e->cap>e->v && d[u]+1==d[pos]) {
                    adv=1;
                    preArc[pos=u]=e;
                    break;
                }
            }
            if(!adv) {
                if(--num[d[pos]]==0)
                    break;
                d[pos]=n;
                for(Edge *e=cArc[pos]=G[pos];e;e=e->pre)
                    if(e->cap>e->v)
                        Reduce(d[pos],d[e->to]+1);
                num[d[pos]]++;
                if(pos!=1)
                    pos=preArc[pos]->rev->to;//cArc
            }
        }
        return flow;
    }
}

int main() {
    //freopen("test1.in","r",stdin);
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    int T;std::cin>>T;
    while(T--) {
        int m;std::cin>>n>>m;
        for(int i=1;i<=n;++i) {
            D::G[i].clear();
            I::G[i]=0;
        }
        for(int i=1;i<=m;++i) {
            int x,y,v;
            std::cin>>x>>y>>v;
            D::G[x].push_back({y,v});
        }

        D::Run();

        if(sp[n]==oo)
            std::cout<<0<<'\n';
        else {
            //蜜汁公式 求出所有最短路径边
            for(int pos=1;pos<=n;++pos)
                for(auto &e : D::G[pos])
                    if(sp[e.to]-sp[pos]==e.v)
                        I::AddEdge(pos,e.to,e.v);

            std::cout<<I::Run()<<'\n';
        }
    }
    return 0;
}
全部评论

相关推荐

一天代码十万三:这都不能算简历吧
点赞 评论 收藏
分享
1.&nbsp;事件概述3月10日下午,华为在“心声社区”发布长达6500字通报,曝光72名正式员工及19名非雇员在非雇员招聘中存在徇私舞弊行为,多人出卖公司信息资产获利,引发热议。-&nbsp;“非雇员”一般指华为OD员工,与人力服务公司签劳动合同,以派遣方式到华为工作,薪资待遇与华为内部员工基本一致,可通过考核转正。2.&nbsp;相关传言与真相华为相关人士称暂无官方回应,很多传言细节不准确。&nbsp;华为成都研究所员工透露,此次通报主要涉及成都研究所的数据存储部门,整个数据存储业务约100余人,此次明文通报除名辞退或通报批评的有62名,“很多部门基本全开除”&nbsp;。网传任正非亲赴成都、封楼抓人等消息不实。早在2024年年中,就有...
七安有出处嘛:省流:任正非亲赴成都等消息不实,2024 年年中就有人举报了;涉及36名违规当事人,其中有13人被除名;10人有主动申报情节或情节较严重的,予以辞退处理;另有13人被劝退、个人职级降3等。另外还有26名相关管理责任人作为直接或间接管理者,被处以个人职级降6等,冻结个人涨薪、职级晋升、干部向上任命,冻结期6—12个月不等;若下属违规偶发,则仅通报批评。并没有释放100HC😂😂😂
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务