HDU 3879 Base Station 最大权闭合图

简介:

题目链接:点击打开链接

题意:

给定n个带权点m条无向带权边

选一个子图。则这个子图的权值为 边权和-点权和

求一个最大的权值


把边也当成点。然后是最大权闭合图

dinic:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
//点标 从0開始 F.Init(n) n=最大点标+10
const int N = 200010;
const int M = 500010;
const int INF = ~0u >> 2;
template<class T>
struct Max_Flow {
    int n;
    int Q[N], sign;
    int head[N], level[N], cur[N], pre[N];
    int nxt[M], pnt[M], E;
    T cap[M];
    void Init(int n) {
        this->n = n;
        E = 0;
        std::fill(head, head + n, -1);
    }
    //有向rw 就= 0
    void add(int from, int to, T c, T rw) {
        pnt[E] = to;
        cap[E] = c;
        nxt[E] = head[from];
        head[from] = E++;

        pnt[E] = from;
        cap[E] = rw;
        nxt[E] = head[to];
        head[to] = E++;
    }
    bool Bfs(int s, int t) {
        sign = t;
        std::fill(level, level + n, -1);
        int *front = Q, *tail = Q;
        *tail++ = t; level[t] = 0;
        while(front < tail && level[s] == -1) {
            int u = *front++;
            for(int e = head[u]; e != -1; e = nxt[e]) {
                if(cap[e ^ 1] > 0 && level[pnt[e]] < 0) {
                    level[pnt[e]] = level[u] + 1;
                    *tail ++ = pnt[e];
                }
            }
        }
        return level[s] != -1;
    }
    void Push(int t, T &flow) {
        T mi = INF;
        int p = pre[t];
        for(int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {
            mi = std::min(mi, cap[p]);
        }
        for(int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {
            cap[p] -= mi;
            if(!cap[p]) {
                sign = pnt[p ^ 1];
            }
            cap[p ^ 1] += mi;
        }
        flow += mi;
    }
    void Dfs(int u, int t, T &flow) {
        if(u == t) {
            Push(t, flow);
            return ;
        }
        for(int &e = cur[u]; e != -1; e = nxt[e]) {
            if(cap[e] > 0 && level[u] - 1 == level[pnt[e]]) {
                pre[pnt[e]] = e;
                Dfs(pnt[e], t, flow);
                if(level[sign] > level[u]) {
                    return ;
                }
                sign = t;
            }
        }
    }
    T Dinic(int s, int t) {
        pre[s] = -1;
        T flow = 0;
        while(Bfs(s, t)) {
            std::copy(head, head + n, cur);
            Dfs(s, t, flow);
        }
        return flow;
    }
};
Max_Flow <int>F;
int n, m;
int work(){
    F.Init(n+m+10);
    int from = 0, to = n + m +1, A;
    for(int i = 1; i <= n; i++){
        scanf("%d", &A);
        F.add(i, to, A, 0);
    }
    int u, v, d, all = 0;
    for(int i = 1; i <= m; i++){
        scanf("%d %d %d", &u, &v, &d);
        all += d;
        F.add(from, n+i, d, 0);
        F.add(n+i, u, INF, 0);
        F.add(n+i, v, INF, 0);
    }
    return all - F.Dinic(from, to);
}
int main(){
    while(cin>>n>>m)
        cout<<work()<<endl;
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define ll int
const int MAXN = 100010;//点数的最大值
const int MAXM = 400010;//边数的最大值
const int INF = 0x3f3f3f3f;
struct Edge
{
    int to,next,cap,flow;
}edge[MAXM];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],cur[MAXN];
void add(int u,int v,int w,int rw = 0)
{
    edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
    edge[tol].next = head[u]; head[u] = tol++;
    edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;
    edge[tol].next = head[v]; head[v] = tol++;
}
int Q[MAXN];
void BFS(int start,int end)
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0] = 1;
    int front = 0, rear = 0;
    dep[end] = 0;
    Q[rear++] = end;
    while(front != rear)
    {
        int u = Q[front++];
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            if(dep[v] != -1)continue;
            Q[rear++] = v;
            dep[v] = dep[u] + 1;
            gap[dep[v]]++;
        }
    }
}
int S[MAXN];
int sap(int start,int end,int N)
{
    BFS(start,end);
    memcpy(cur,head,sizeof(head));
    int top = 0;
    int u = start;
    int ans = 0;
    while(dep[start] < N)
    {
        if(u == end)
        {
            int Min = INF;
            int inser;
            for(int i = 0;i < top;i++)
                if(Min > edge[S[i]].cap - edge[S[i]].flow)
                {
                    Min = edge[S[i]].cap - edge[S[i]].flow;
                    inser = i;
                }
            for(int i = 0;i < top;i++)
            {
                edge[S[i]].flow += Min;
                edge[S[i]^1].flow -= Min;
            }
            ans += Min;
            top = inser;
            u = edge[S[top]^1].to;
            continue;
        }
        bool flag = false;
        int v;
        for(int i = cur[u]; i != -1; i = edge[i].next)
        {
            v = edge[i].to;
            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])
            {
                flag = true;
                cur[u] = i;
                break;
            }
        }
        if(flag)
        {
            S[top++] = cur[u];
            u = v;
            continue;
        }
        int Min = N;
        for(int i = head[u]; i != -1; i = edge[i].next)
            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
            {
                Min = dep[edge[i].to];
                cur[u] = i;
            }
        gap[dep[u]]--;
        if(!gap[dep[u]])return ans;
        dep[u] = Min + 1;
        gap[dep[u]]++;
        if(u != start)u = edge[S[--top]^1].to;
    }
    return ans;
}
void init(){ tol = 0; memset(head,-1,sizeof(head)); }

int n, m;
ll work(){
    init();
    int from = 0, to = n + m +1, A;
    for(int i = 1; i <= n; i++){
        scanf("%d", &A);
        add(i, to, A);
    }
    int u, v; ll d;
    ll all = 0;
    for(int i = 1; i <= m; i++){
        scanf("%d %d %d", &u, &v, &d);
        all += d;
        add(from, n+i, d);
        add(n+i, u, INF);
        add(n+i, v, INF);
    }
    return all - sap(from, to,to+1);
}
int main(){
    while(cin>>n>>m)
        cout<<work()<<endl;
    return 0;
}







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5250126.html,如需转载请自行联系原作者

相关文章
|
存储 安全 机器人
如何下载阿里云视频点播数据
如何下载阿里云视频点播(VOD)数据
903 0
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
316 1
|
前端开发 JavaScript 开发者
Bottle 也太厉害了吧!轻量级 Web 开发的神奇魔法,你还不来试试?
【8月更文挑战第31天】Bottle是一个轻量级且功能全面的Python Web框架,以其高效、简洁的特点受到开发者青睐。通过简单的安装步骤即可快速搭建Web应用。本文档不仅介绍了如何使用Bottle创建基础的路由和响应,还展示了模板渲染、静态文件处理及表单操作等功能,帮助读者快速上手并充分发挥其潜力。
380 1
|
8月前
|
数据可视化 图形学 UED
从模型托管到交互开发:DataV 如何简化三维 Web 应用构建?
从模型托管到交互开发:DataV 如何简化三维 Web 应用构建?
223 2
|
Apache 数据安全/隐私保护
HAProxy的高级配置选项-ACL篇之基于策略的访问控制
这篇文章介绍了HAProxy的高级配置选项,特别是如何使用ACL(访问控制列表)进行基于策略的访问控制,通过实战案例展示了如何配置HAProxy以允许或拒绝来自特定源地址的访问。
258 6
HAProxy的高级配置选项-ACL篇之基于策略的访问控制
|
存储 负载均衡 算法
分布式-Zookeeper-Master选举
分布式-Zookeeper-Master选举
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
存储 NoSQL 定位技术
如何在Redis中快速推算两地之间的距离?——Geo篇
Redis 3.2 引入Geo类型,支持地理位置数据存储和计算,如距离和范围查询。使用`GEOADD`将城市经纬度添加至`zset`中,通过`GEOPOS`获取坐标,`GEODIST`计算距离,`GEORADIUS`查找指定范围内的城市。Redis的Geo功能适用于快速的地理位置服务,如附近搜索和配送范围分析。利用`ZSET`操作可增删位置数据,简化地理空间应用开发。
355 0
|
消息中间件 架构师 NoSQL
以架构师的视角,深入剖析如何设计订单超时自动取消的功能
我们在美团 APP 下单,假如没有立即支付,进入订单详情会显示倒计时,如果超过支付时间,订单就会被自动取消。 这篇文章,笔者想以架构师的视角,深入剖析如何设计订单超时自动取消的功能。
以架构师的视角,深入剖析如何设计订单超时自动取消的功能
|
网络协议
rtmp改udp推流,并测试延时性能
rtmp改udp推流,并测试延时性能
530 0
rtmp改udp推流,并测试延时性能