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;
    }
}

 

posted @ 2019-07-25 18:35  Isakovsky  阅读(250)  评论(0编辑  收藏  举报