码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2561 最小生成树

时间:2014-10-23 17:46:23      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:style   color   io   os   ar   for   sp   on   amp   

题目大意:给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最少多少条边,才能够使得这条边既可能出现在最小生成树上,也可能出现在最大生成树上?


思路:对于某一条边,如果用小于这条边边权的所有边中的一部分就能够使得这条边的两个端点连通,那么这一条边必然不会出现在最小生成树中。最大生成树同理。

那么等价于求出删除最少的边,使得小于该边权的边不能使得两个端点连通,大于该边权的边也不能使得两个端点连通。

于是分别建图求最小割即可。


Code:

#include <queue>
#include <cstdio>
#include <cstring>
#include <climits>
#include <iostream>
#include <algorithm>
using namespace std;
 
#define N 20010
#define M 200010
struct Edge {
    int f, t, len;
    void read() {
        scanf("%d%d%d", &f, &t, &len);
    }
}E[M];
 
#define INF 0x3f3f3f3f
queue<int> q;
struct Solver {
    int head[N], next[M << 1], end[M << 1], flow[M << 1], ind;
    int d[N], gap[N], stack[N], top, cur[N];
    void reset() {
        ind = top = 0;
        memset(head, -1, sizeof head);
    }
    void addedge(int a, int b, int _flow) {
        int q = ind++;
        end[q] = b;
        next[q] = head[a];
        head[a] = q;
        flow[q] = _flow;
    }
    void addedge_db(int a, int b, int _flow) {
        addedge(a, b, _flow);
        addedge(b, a, _flow);
    }
    void make(int a, int b, int _flow) {
        addedge(a, b, _flow);
        addedge(b, a, 0);
    }
    void bfs(int T) {
        memset(d, -1, sizeof d);
        memset(gap, 0, sizeof gap);
        ++gap[d[T] = 0];
        int i, j;
        q.push(T);
        while(!q.empty()) {
            i = q.front();
            q.pop();
            for(j = head[i]; j != -1; j = next[j])
                if (d[end[j]] == -1)
                    ++gap[d[end[j]] = d[i] + 1], q.push(end[j]);
        }
    }
    int Maxflow(int S, int T) {
        int Min, ins, res = 0;
        memcpy(cur, head, sizeof(cur));
        bfs(T);
        int u = S;
        while(d[S] < (T - S + 1)) {
            if (u == T) {
                Min = INF;
                for(int i = 0; i < top; ++i)
                    if (flow[stack[i]] < Min)
                        Min = flow[stack[i]], ins = i;
                for(int i = 0; i < top; ++i) {
                    flow[stack[i]] -= Min;
                    flow[stack[i] ^ 1] += Min;
                }
                res += Min;
                u = end[stack[top = ins] ^ 1];
            }
            if (u != T && !gap[d[u] - 1])
                break;
            bool find = 0;
            for(int &j = cur[u]; j != -1; j = next[j])
                if (flow[j] && d[end[j]] + 1 == d[u]) {
                    find = 1;
                    ins = j;
                    break;
                }
            if (find) {
                stack[top++] = ins;
                cur[u] = ins;
                u = end[ins];
            }
            else {
                Min = T - S + 1;
                for(int j = head[u]; j != -1; j = next[j]) {
                    if (flow[j] && d[end[j]] < Min) {
                        Min = d[end[j]];
                        cur[u] = j;
                    }
                }
                if (!--gap[d[u]])
                    break;
                ++gap[d[u] = Min + 1];
                if (u != S)
                    u = end[stack[--top] ^ 1];
            }
        }
        return res;
    }
}G;
 
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
     
    register int i, j;
    for(i = 1; i <= m; ++i)
        E[i].read();
     
    int u, v, L;
    scanf("%d%d%d", &u, &v, &L);
     
    int tot = 0;
    G.reset();
    G.make(0, u, INF);
    G.make(v, n + 1, INF);
    for(i = 1; i <= m; ++i)
        if (E[i].len < L)
            G.addedge_db(E[i].f, E[i].t, 1);
    tot += G.Maxflow(0, n + 1);
     
    G.reset();
    G.make(0, u, INF);
    G.make(v, n + 1, INF);
    for(i = 1; i <= m; ++i)
        if (E[i].len > L)
            G.addedge_db(E[i].f, E[i].t, 1);
    tot += G.Maxflow(0, n + 1);
     
    printf("%d", tot);
     
    return 0;
}


BZOJ2561 最小生成树

标签:style   color   io   os   ar   for   sp   on   amp   

原文地址:http://blog.csdn.net/wyfcyx_forever/article/details/40400163

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!