bzoj5037: [Jsoi2014]电信网络

来源:互联网 发布:知乎最高赞用户 编辑:程序博客网 时间:2024/04/28 21:32

bzoj5037: [Jsoi2014]电信网络


http://www.lydsy.com/JudgeOnline/problem.php?id=5037

考虑约束关系的实质即是选择一个点必须选择能被他到达的点,考虑最小割建图。

#include <bits/stdc++.h>using namespace std;const int MAXN = 505;struct node {    int to, next, flow, neg;} edge[MAXN*MAXN*3];int head[MAXN], top = 0;const int S = MAXN-1, T = MAXN-2;inline void push(int i, int j, int f){    ++top, edge[top] = (node){j, head[i], f, top+1}, head[i] = top;    ++top, edge[top] = (node){i, head[j], 0, top-1}, head[j] = top;}int vis[MAXN], bfstime, lev[MAXN];int cur[MAXN];int q[MAXN], L, R;bool bfs(){    L = 1, R = 0, q[++R] = S, vis[S] = ++bfstime, lev[S] = 0;    while (L <= R) {        int nd = q[L++];        for (int i = head[nd]; i; i = edge[i].next) {            int to = edge[i].to;            if (vis[to] == bfstime || edge[i].flow == 0) continue;            lev[to] = lev[nd]+1, vis[to] = bfstime, q[++R] = to;        }    }    return vis[T] == bfstime;}int dfs(int nd, int flow){    if (nd == T || flow == 0) return flow;    int ans = 0, t;    for (int &i = cur[nd]; i; i = edge[i].next) {        int to = edge[i].to;        if (lev[to] != lev[nd]+1 || edge[i].flow == 0) continue;        t = dfs(to, min(flow, edge[i].flow));        ans += t, flow -= t, edge[i].flow -= t, edge[edge[i].neg].flow += t;    }    return ans;}int dinic(){    int ans = 0;    while (bfs()) memcpy(cur, head, sizeof head), ans += dfs(S, INT_MAX);    return ans;}int n;int x[MAXN], y[MAXN], r[MAXN], s[MAXN];int main(){    scanf("%d", &n);    int INF = 1e5;    for (int i = 1; i <= n; i++) {        scanf("%d%d%d%d", &x[i], &y[i], &r[i], &s[i]);        push(S, i, INF), push(i, T, -s[i]+INF);    }    for (int i = 1; i <= n; i++)        for (int j = 1; j <= n; j++) {            if (i == j) continue;            if ((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]) > r[i]*r[i]) continue;            push(i, j, INT_MAX);        }    cout << -(dinic()-n*INF) << endl;    return 0;}
原创粉丝点击