【BNUOJ】Another Server

来源:互联网 发布:知乎为什么垃圾 编辑:程序博客网 时间:2024/05/17 02:00

第十五届北京师范大学程序设计竞赛决赛

A. Another Server

何老师某天在机房里搞事情的时候,发现机房里有n台服务器,从1n标号,同时有2n2条网线,从12n2标号,其中第i条网线双向连接着i+12号服务器和i+12+1号服务器,在一个单位时间内最多能够承受xi个单位流量。

显然这些服务器之间要进行信息交换,为了测试服务器的抗压能力,你需要帮何老师计算出1号服务器在一个单位时间内最多能向n号服务器发送多少个单位流量的数据,这里认为数据的传输是瞬间完成的。
这里写图片描述
(该图引用自百度百科)

Input

第一行是一个正整数T(1000),表示测试数据的组数,对于每组测试数据,第一行是一个整数n(2n100),表示服务器的数量,

第二行包含2n2个以空格分隔的正整数x1,x2,...,x2n2,表示网线单位时间内能承受的流量,保证不超过100

Output

对于每组测试数据,输出一个整数,表示1号服务器在一个单位时间内最多能向n号服务器发送的数据量。

Sample Input

2
2
1 1
3
1 3 2 4

Sample Output

2
4

Hint

x表示不大于x的最大整数,例如1.5=1,2=2

题解

1为源点n为汇点,按照题目中的要求建边,跑最大流即可。

代码

#include <bits/stdc++.h>using namespace std;const int maxn = 510;const int inf = 1e9+1;int T, n, m;int head[maxn], nxt[maxn], to[maxn], flow[maxn], mxflow[maxn], cnt;int dep[maxn], q[maxn], cur[maxn];bool vis[maxn];void add(int a, int b, int c){    nxt[++ cnt] = head[a], to[head[a] = cnt] = b, mxflow[cnt] = c, flow[cnt] = 0;    nxt[++ cnt] = head[b], to[head[b] = cnt] = a, mxflow[cnt] = 0, flow[cnt] = 0;}bool bfs(){    for(int i = 1; i <= n; i ++){        vis[i] = 0, dep[i] = 0;    }    int l = 1, r = 0; q[++ r] = 1, vis[1] = 1, dep[1] = 1;    while(l <= r){        int x = q[l ++];        for(int i = head[x]; i; i = nxt[i]){            int u = to[i];            if(!vis[u] && flow[i] < mxflow[i]){                q[++ r] = u, dep[u] = dep[x] + 1, vis[u] = 1;             }        }    }    return vis[n];}int dfs(int x, int mr){    if(x == n || mr == 0) return mr;    int &i = cur[x];    int f = 0, res = 0, u;    for( ; i; i = nxt[i]){        u = to[i];        if(dep[x]+1 == dep[u] && (f = dfs(u, min(mr, mxflow[i] - flow[i])))){            flow[i] += f, flow[i^1] -= f;            mr -= f, res += f;        }        if(mr == 0) break;    }     return res;}int dinic(){    int res = 0;    while(bfs()){        for(int i = 1; i <= n; i ++) cur[i] = head[i];        res += dfs(1, inf);    }    return res;}int main(){    scanf("%d", &T);    while(T --){        scanf("%d", &n);        m = 2*n-2, cnt = 1;        for(int i = 1; i <= n; i ++) head[i] = 0;        for(int i = 1; i <= m; i ++){            int v; scanf("%d", &v);            add((i+1)/2, (i+1)/2+1, v);        }         printf("%d\n", dinic());    }     return 0;} 
0 0