[最小割最大流 || 最短路] roadblock Dinic && SPFA + SLE

来源:互联网 发布:美国历年非农数据统计 编辑:程序博客网 时间:2024/06/06 09:37

大家都很强, 可与之共勉。

震惊!cky 竟率兵攻打jyb!
jyb 面对强敌,振作精神,想要抗击侵略。jyb 的国家一共有n 个城市,m 条距离为1 的双向道路。现在jyb的所在地是1 号城市,cky 已经占领了n 号城市。jyb 得到线报,cky 想要走最近的路线抓到自己,而jyb 还在调集部队,所以他希望拖延一点时间。他派出了一些工程人员去破坏道路,破坏每条道路都要消耗一定的资源,jyb 希望消耗最小的资源并且保证能拖延到cky。

Input
第1 行,1 个整数T, 表示数据组数,对于每组数据:
第1 行,2 个整数n;m,表示城市数和道路数
接下来m 行,每行3 个整数u; v;w, 表示城市u 到城市v 有一条路,破坏消耗的资源为w。
Output
对于每组数据,输出最小消耗的资源。
Sample
roadblock.in
1
4 4
1 2 1
2 4 2
3 1 3
4 3 4
roadblock.out
4

数据范围:
1  T  5, 1  n  1000,1  m  10000,1  w  300000。

题意其实挺简单的,先BFS找出最短路,因为边权为1,最短路显然有很多,然后我们建一个只有最短路上边的新图,然后跑出最小割就好。需要加当前弧优化才能过所有点。

调了我好久啊, 天哪!

#include "queue"#include "cctype"#include "cstdio"#include "cstring"#define max(a, b)  ((a) > (b) ? (a) : (b))#define min(a, b)  ((a) < (b) ? (a) : (b))#define rep(i, m, n)  for(register int i = (m); i <= (n); ++i)#define edges(u)  for(register int i = head[u]; i; i = g[i].pre)template <class T>inline bool readIn(T &x)  {    T opt = 1;    static char ch;    while(!isdigit(ch = (char) getchar()) && (ch ^ -1) && (ch ^ 45));    if(ch == -1)  return false;    if(ch == 45)  opt = -1, ungetc(ch, stdin);    for(x = -48 + ch; isdigit(ch = (char) getchar()); x = (x << 1) + (x << 3) + ch - 48);    x *= opt;    return true;}template <class T>inline bool writeIn(T x)  {    T st[25], top = 0;    if(x < 0)  putchar('-'), x = -x;    if(x == 0)  {  putchar(48); return true;  }    while(x)  st[++top] = x % 10, x /= 10;    while(top)  putchar(st[top--] + 48);    return true;}const int oo = 0x3f3f3f3f;struct edge  {    int to, pre, cost;    edge(int to = 0, int pre = 0, int cost = 0) : to(to), pre(pre), cost(cost) {  }} g[20005];struct Edge  {    int to, cap, flow, pre;    Edge(int to = 0, int flow = 0, int cap = 0, int pre = 0) : to(to), flow(flow), cap(cap), pre(pre) {  }} e[20005];typedef long long LL;int T, n, m, tot, ne, head[10005], dis1[10005], dis2[10005], u[10005], v[10005], w[10005];LL ans;void SPFA(int s, int t)  {    static std::deque<int> q;    static bool vis[10005];    memset(dis1, 0x3f, sizeof (int) * (n + 1));    memset(dis2, 0x3f, sizeof (int) * (n + 1));    memset(vis, false, sizeof (int) * (n + 1));    q.push_front(s); vis[s] = true; dis1[s] = 0;    while( !q.empty() )  {        int u = q.front(); q.pop_front();        vis[u] = false;        edges(u)  {            int v = g[i].to;            if( dis1[v] > dis1[u] + 1 )  {                dis1[v] = dis1[u] + 1;                if( !vis[v] )  {                    if( q.empty() || dis1[v] < dis1[q.front()] )                        q.push_front(v);                    else                        q.push_back(v);                    vis[v] = true;                }            }        }    }    memset(vis, false, sizeof (int) * (n + 1));    q.push_front(t); vis[t] = true; dis2[t] = 0;    while( !q.empty() )  {        int u = q.front(); q.pop_front();        vis[u] = false;        edges(u)  {            int v = g[i].to;            if( dis2[v] > dis2[u] + 1 )  {                dis2[v] = dis2[u] + 1;                if( !vis[v] )  {                    if( q.empty() || dis2[v] < dis2[q.front()] )                        q.push_front(v);                    else                        q.push_back(v);                    vis[v] = true;                }            }        }    }}class Dinic  {public:    int d[10005], cur[10005], s, t;    std::queue<int> Q;    bool vis[10005];     bool bfs(int s, int t)  {               memset(vis, false, sizeof (int) * (n + 1));        d[s] = 0, vis[s] = true;        Q.push(s);        while(!Q.empty())  {            int u = Q.front();  Q.pop();            for( int i = head[u]; i; i = e[i].pre )  {                int v = e[i].to;                if( !vis[v] && e[i].cap > e[i].flow )  {                    vis[v] = true;                    d[v] = d[u] + 1;                    Q.push(v);                }            }        }        return vis[t];    }    int dfs( int u, int a )  {        if( u == t || !a )  return a;        int flow = 0, f;        for(register int &i = cur[u]; i; i = e[i].pre )  {            int  v = e[i].to;            if( d[u] + 1 == d[v] && (f = dfs(v, min(e[i].cap - e[i].flow, a))) > 0)  {                e[i].flow += f;                e[i^1].flow -= f;                flow += f;                a -= f;                if(!a)  return flow;            }        }        return flow;    }    int Maxflow( int s, int t )  {        this->s = s, this->t = t;        int flow = 0;        while( bfs( s, t ) )  {            rep(i, 1, n)  cur[i] = head[i];            flow += dfs( s, oo );        }        return flow;    }} M;#define adde(u, v, cost)  { g[++ne] = edge(v, head[u], cost); head[u] = ne; }inline void initialize()  {    readIn(n);readIn(m); ne = 1, tot = 0;    memset(head, 0, sizeof (int) * (n + 1));    int x, y, o;    while( m-- )  {        readIn(x);readIn(y);readIn(o);        adde(x, y, o);adde(y, x, o);    }    SPFA(1, n);    rep(x, 1, n)  edges(x)  if(dis1[x] + dis2[g[i].to] + 1 == dis1[n])  { u[++tot] = x, v[tot] = g[i].to, w[tot] = g[i].cost; }    ne = 1;    memset(head, 0, sizeof (int) * (n + 1));    rep(i, 1, tot)  {        e[++ne] = Edge(v[i], 0, w[i], head[u[i]]); head[u[i]] = ne;          e[++ne] = Edge(u[i], 0, 0, head[v[i]]); head[v[i]] = ne;    }}int main()  {    freopen("roadblock.in", "r", stdin);    freopen("roadblock.out", "w", stdout);    for(readIn(T); T; --T)  {        initialize();        writeIn(M.Maxflow(1, n));        putchar(10);    }}
0 0
原创粉丝点击