zoukankan      html  css  js  c++  java
  • [题解] [JSOI2014] 电信网络

    题面

    题解

    选某个点就必须选其他的点

    最大权闭合子图

    Code

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    const int N = 505;
    const int INF = 0x3f3f3f3f; 
    using namespace std;
    
    int n, x[N], y[N], r[N], S, T, cnt = 1, head[N], d[N], cur[N], sum;
    struct edge { int to, nxt, flow; } e[N * N * 4];
    queue<int> q; 
    
    template < typename T >
    inline T read()
    {
        T x = 0, w = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * w; 
    }
    
    int mabs(int x) { return x > 0 ? x : -x; }
    
    inline void adde(int u, int v, int w)
    {
        e[++cnt] = (edge) { v, head[u], w }, head[u] = cnt;
        e[++cnt] = (edge) { u, head[v], 0 }, head[v] = cnt; 
    }
    
    bool check(int i, int j) { return mabs(x[i] - x[j]) * mabs(x[i] - x[j]) + mabs(y[i] - y[j]) * mabs(y[i] - y[j]) <= r[i] * r[i]; }
    
    bool bfs()
    {
        memset(d, 0, sizeof(d)), d[S] = 1, q.push(S);
        while(!q.empty())
        {
    	int u = q.front(); q.pop();
    	for(int v, i = head[u]; i; i = e[i].nxt)
    	{
    	    v = e[i].to;
    	    if(!d[v] && e[i].flow > 0)
    		d[v] = d[u] + 1, q.push(v); 
    	}
        }
        return d[T]; 
    }
    
    int dfs(int u, int a)
    {
        if(u == T || !a) return a;
        int f = 0;
        for(int v, &i = cur[u]; i; i = e[i].nxt)
        {
    	v = e[i].to;
    	if(e[i].flow > 0 && d[v] == d[u] + 1)
    	{
    	    int tmp = dfs(v, min(a, e[i].flow));
    	    f += tmp, a -= tmp, e[i].flow -= tmp, e[i ^ 1].flow += tmp; 
    	}
    	if(!a) break; 
        }
        if(a) d[u] = 0;
        return f; 
    }
    
    int dinic()
    {
        int flow = 0;
        while(bfs())
    	memcpy(cur, head, sizeof(cur)), flow += dfs(S, INF);
        return flow; 
    }
    
    int main()
    {
        n = read <int> (), S = n + 1, T = S + 1;
        for(int k, i = 1; i <= n; i++)
        {
    	x[i] = read <int> (), y[i] = read <int> (), r[i] = read <int> ();
    	k = read <int> ();
    	if(k > 0) sum += k, adde(S, i, k);
    	else adde(i, T, -k); 
        }
        for(int i = 1; i <= n; i++)
    	for(int j = 1; j <= n; j++)
    	    if(i != j && check(i, j)) adde(i, j, INF); 
        printf("%d
    ", sum - dinic()); 
        return 0; 
    }
    
  • 相关阅读:
    为什么C++(感谢waterwalk翻译)
    容器操作笔记
    如此理解面向对象编程
    C++初学者小细节(不定时更新)
    Sales_item 专题
    10步让你成为更优秀的程序员
    C++ PRIMER 笔记
    C++ 异常处理
    透明度 rgba 和 opacity 的区别
    盒模型
  • 原文地址:https://www.cnblogs.com/ztlztl/p/12296686.html
Copyright © 2011-2022 走看看