您的位置:首页 > 理论基础 > 计算机网络

bzoj5037: [Jsoi2014]电信网络

2017-11-30 19:09 375 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: