zoukankan      html  css  js  c++  java
  • HDU6582 Path(最短路+最小割)

    题意:

    查询一个边集,使得这个图里起点到终点的最短路径变长。

    题解:

    先用spfa跑一遍最短路,把不在最短路径上的边权设为0,然后跑一遍Dinic算法求最大流/最小割。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const ll inf=1e18;
    const int maxn=1e5;
    int N,M,T;
    int head[maxn];
    int tol;
    struct node {
        int u;
        int v;
        ll w;
        int next;
    }edge[maxn];
    void addedge (int u,int v,ll w) {
        edge[tol].u=u;
        edge[tol].v=v;
        edge[tol].w=w;
        edge[tol].next=head[u];
        head[u]=tol++;
    }
    ll d[maxn];
    int visit[maxn];
    void spfa (int s) {
        for (int i=1;i<=N;i++)
            d[i]=inf; 
        d[s]=0;
        queue<int> q;
        q.push(s);
        visit[s]=1;
        while (!q.empty()) {
            int u=q.front();
            q.pop();
            visit[u]=0;
            for (int i=head[u];i!=-1;i=edge[i].next) {
                int v=edge[i].v;
                if (edge[i].w>0&&d[v]>d[u]+edge[i].w) {
                    d[v]=d[u]+edge[i].w;
                    if (!visit[v]) {
                        q.push(v);
                        visit[v]=1;
                    }
                }
            }
        } 
    }
    
    ll dep[maxn];
    ll inque[maxn];
    ll vi;
    ll cur[maxn];
    ll maxflow=0;
    int s,t;
    bool bfs () {
        for (int i=0;i<=N;i++) 
            cur[i]=head[i],dep[i]=inf,inque[i]=0;
        dep[s]=0;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int u=q.front();
            q.pop();
            inque[u]=0;
            for (int i=head[u];i!=-1;i=edge[i].next) {
                int v=edge[i].v;
                if (dep[v]>dep[u]+1&&edge[i].w) {
                    dep[v]=dep[u]+1;
                    if (inque[v]==0) {
                        q.push(v);
                        inque[v]=1;
                    }
                }
            }
        } 
        if (dep[t]!=inf) return 1;
        return 0;
    }
    
    ll dfs (int u,ll flow) {
        ll increase=0;
        if (u==t) {
            vi=1;
            maxflow+=flow;
            return flow;
        }
        ll used=0;
        for (int i=cur[u];i!=-1;i=edge[i].next) {
            cur[u]=i;
            int v=edge[i].v;
            if (edge[i].w&&dep[v]==dep[u]+1) {
                if (increase=dfs(v,min(flow-used,edge[i].w))) {
                    used+=increase;
                    edge[i].w-=increase;
                    edge[i^1].w+=increase;
                    if (used==flow) break;
                }
            }
        }
        return used;
    }
    
    
    ll Dinic () {
        while (bfs()) {
            vi=1;
            while (vi==1) {
                vi=0;
                dfs(s,inf);
            }
        }
        return maxflow;
    }
    int main () {
        scanf("%d",&T);
        while (T--) {
            memset(head,-1,sizeof(head));
            tol=0;
            maxflow=0;
            scanf("%d%d",&N,&M);
            for (int i=1;i<=M;i++) {
                int u,v;
                ll w;
                scanf("%d%d%lld",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,0);
            }
            spfa(1);
            for (int i=1;i<=N;i++) {
                for (int j=head[i];j!=-1;j=edge[j].next) 
                    if (d[edge[j].v]!=d[i]+edge[j].w) 
                        edge[j].w=0;
            }
            s=1;
            t=N;
            printf("%lld
    ",Dinic());
        }
        return 0;
    }
  • 相关阅读:
    Block深入浅出
    JSPatch 遇上swift
    iPhone左下角app图标
    Handoff使用指南
    实习任务——导出excel
    实习任务——对查询结果进行筛选过滤
    Markdown基本语法
    学习笔记(二)——类加载及执行顺序
    #学习笔记(一)——static
    写给过去的3年,拥抱2016
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12494059.html
Copyright © 2011-2022 走看看