UVA - 11865 Stream My Contest(朱刘算法)

来源:互联网 发布:苹果电脑能编程吗 编辑:程序博客网 时间:2024/06/11 23:22

题目大意:有n台机器(编号为0—n-1,其中机器0是服务器),m条网线(每条网线相当于一条有向边,有相应的带宽和代价),c的钱

现在要求用m条网线搭建一个网路,使得每台机器都可以从服务器接收到信息,且带宽的最小值达到最大

解题思路:朱刘算法的模版题了,不过加了一个条件,要二分,只要二分一下带宽,在判断一下能否网线能否被使用就可以了
如果连最小的带宽都弄不了,那就表明网路无法建成了,因为枚举值为最小带宽时,每条网线都可以用

#include <cstdio>#include <cstring>#define N 100#define M 10010#define INF 0x3f3f3f3f#define min(a,b) ((a)<(b)?(a):(b))#define max(a,b) ((a)>(b)?(a):(b))#define ll long longstruct Edge{    int from, to, b, c;}E[M*2];int id[N], pre[N], in[N], vis[N];int tot, n, m, C, Max, Min;void AddEdge(int u, int v, int b, int c) {    E[tot + M].from = E[tot].from = u;    E[tot + M].to = E[tot].to = v;     E[tot + M].b = E[tot].b = b;     E[tot + M].c = E[tot].c = c;     tot++;}void init() {    scanf("%d%d%d", &n, &m, &C);    Max = -INF; Min = INF;    tot = 0;    int u, v, b, c;    for (int i = 0; i < m; i++) {        scanf("%d%d%d%d", &u, &v, &b, &c);        AddEdge(u, v, b, c);        Max = max(Max, b);        Min = min(Min, b);    }}bool Directed_MST(int root, int limit, int n) {    ll ans = 0;    while (1) {        memset(pre, -1, sizeof(pre));        for (int i = 0; i < n; i++)             in[i] = INF;        int u, v;        for (int i = 0; i < m; i++) {            u = E[i].from;            v = E[i].to;            if (u != v && E[i].b >= limit && E[i].c < in[v]) {                in[v] = E[i].c;                pre[v] = u;            }        }        for (int i = 0; i < n; i++) {            if (i == root)                continue;            if (in[i] == INF)                return false;        }        int subnode = 0, tmp;        memset(vis, -1, sizeof(vis));        memset(id, -1, sizeof(id));        in[root] = 0;        for (int i = 0; i < n; i++) {            ans += in[i];            tmp = i;            while (vis[tmp] != i && tmp != root && id[tmp] == -1) {                vis[tmp] = i;                tmp = pre[tmp];            }            if (tmp != root && id[tmp] == -1) {                u = pre[tmp];                while (u != tmp) {                    id[u] = subnode;                     u = pre[u];                }                id[tmp] = subnode++;            }        }        if (subnode == 0)            break;        for (int i = 0; i < n; i++) {            if (id[i] == -1)                id[i] = subnode++;        }        for (int i = 0; i < m; i++) {            tmp = E[i].to;            E[i].from = id[E[i].from];            E[i].to = id[E[i].to];            if (E[i].from != E[i].to)                E[i].c -= in[tmp];        }        root = id[root];        n = subnode;    }    if (ans <= C)        return true;    return false;}void solve() {    if (!Directed_MST(0, Min, n)) {        printf("streaming not possible.\n");        return ;    }    int r = Max, l = Min, mid;    while (l < r) {        mid = l + (r - l + 1) / 2;        for (int i = 0; i < m; i++)            E[i] = E[i + M];        if (Directed_MST(0, mid, n))            l = mid;        else            r = mid - 1;    }    printf("%d kbps\n", r);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击