• hdu多校第一场1005(hdu6582)Path 最短路/网络流


    题意:

    在无向图上删边,让此图上从起点到终点的最短路长度变大,删边的代价是边长,求最小代价。

    题解:

    先跑一遍迪杰斯特拉,求出所有点的d[]值,然后在原图上保留所有的边(i,j)仅当i,j满足d[j]-d[i]=l(i,j),在这个图上跑最小割。

    时间复杂度O((E)logV+V^2*E)

    #include <bits/stdc++.h>
    #pragma GCC optimize(2)
    using namespace std;
    typedef long long LL;
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    const int M = 1e5 + 5;
    const LL mod = 1e9 + 7;
    const double eps = 1e-11;
    const double pi = acos(-1);
    const int INF = 0x3f3f3f3f;
    const LL lINF = 0x3f3f3f3f3f3f3f3f;
    const int maxn = 2e5 + 10;
    const int N = 32;
    int level[M];//顶点到源点的距离标号
    int iter[M];//当前弧
    int t;
    int n, m;
    struct edge {
        int to;
        LL cap, rev;
        edge(int t, LL c, LL r) :to(t), cap(c), rev(r) {}
    };
    struct Edge {
        int v;
        LL w;
        Edge() {}
        Edge(int a, LL b) { v = a; w = b; }
    };
    vector<Edge> edge1[M];
    vector<edge> g[M];
    void init(int n)
    {
        for (int i = 1; i <= n; i++)
        {
            g[i].clear();
            edge1[i].clear();
        }
        memset(level, -1, sizeof(level));
        memset(iter, 0, sizeof(iter));
    }
    void addedge(int from, int to, LL cap)
    {
        g[from].push_back(edge(to, cap, g[to].size()));
        g[to].push_back(edge(from, 0, g[from].size() - 1));
    }
    void bfs(int s)
    {
        memset(level, -1, sizeof(level));
        queue<int>que;
        level[s] = 0;
        que.push(s);
        while (!que.empty())
        {
            int v = que.front();
            que.pop();
            for (int i = 0; i < g[v].size(); i++)
            {
                edge &e = g[v][i];
                if (e.cap > 0 && level[e.to] < 0)
                {
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
        }
    }
    LL dfs(int v, int t, LL f)
    {
        if (v == t)
            return f;
        for (int &i = iter[v]; i < g[v].size(); i++)
        {
            edge &e = g[v][i];
            if (e.cap > 0 && level[v] < level[e.to])
            {
                LL d = dfs(e.to, t, min(f, e.cap));
                if (d > 0)
                {
                    e.cap -= d;
                    g[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    LL maxflow(int s, int t)
    {
        LL flow = 0;
        while (1)
        {
            bfs(s);
            if (level[t] < 0)
                return flow;
            memset(iter, 0, sizeof(iter));
            LL f;
            while ((f = dfs(s, t, INF)) > 0)
            {
                flow += f;
            }
        }
    }
    int isv[M];
    LL d[M];
    int tot;
    struct node {
        int u;
        LL dis;
        node() {}
        node(int a, LL b) { u = a; dis = b; }
        bool operator <(const node & a)const
        {
            if (dis == a.dis)
                return u < a.u;
            else
                return dis > a.dis;
        }
    };
    
    struct edge2 {
        int u, v;
        LL cost;
    }ed2[M*2];
    void dikjstra(int s)
    {
        for (int i = 0; i <= n; i++)
        {
            d[i] = lINF;
            isv[i] = 0;
        }
        d[s] = 0;
        priority_queue<node>que;
        que.push(node(s, d[s]));
        while (!que.empty())
        {
            node nw = que.top();
            que.pop();
            int u = nw.u;
            isv[u] = 1;
            for (int i = 0; i < edge1[u].size(); i++)
            {
                int v = edge1[u][i].v;
                LL w = edge1[u][i].w;
                if (isv[v])
                    continue;
                if (d[v] > d[u] + w)
                {
                    d[v] = d[u] + w;
                    que.push(node(v, d[v]));
                }
            }
        }
    
    }
    void addedge1(int a, int b, LL c)
    {
        edge1[a].push_back(Edge(b, c));
    }
    void addedge2(int u, int v, LL cost)
    {
        ed2[tot].u = u;
        ed2[tot].v = v;
        ed2[tot++].cost = cost;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> t;
        while (t--)
        {
            cin >> n >> m;
            init(n);
            tot = 0;
            for (int i = 0; i < m; i++)
            {
                int u, v;
                LL cost;
                cin >> u >> v >> cost;
                addedge1(u, v, cost);
                addedge2(u, v, cost);
            }
            if (n == 1)
            {
                cout << 0 << endl;
                continue;
            }
            dikjstra(1);
            for (int i = 0; i < m; i++)
            {
                if (d[ed2[i].u] + ed2[i].cost == d[ed2[i].v])
                {
                    addedge(ed2[i].u, ed2[i].v, ed2[i].cost);
                }
            }
            cout << maxflow(1, n) << endl;
        }
    }
  • 相关阅读:
    CSS选择器之伪类选择器(元素)
    CSS选择器之基本选择器+属性选择器
    bugku 点击1000000次
    bugku web 5
    bugku 矛盾 30
    bugku 域名解析题 50
    bugku 好多压缩包
    六子冲 模拟棋盘
    poj3126 Prime Path(c语言)
    poj1426 Find The Multiple(c语言巧解)
  • 原文地址:https://www.cnblogs.com/isakovsky/p/11246178.html
Copyright © 2020-2023  润新知