HDU3917 最大权闭合图

题目链接


http://acm.hdu.edu.cn/showproblem.php?pid=3917
 题目就是最大权闭合图的模板题,,然后ek会t于是上网学了一发sap。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define FF(i,NV) for(int i=0;i<NV;i++)
using namespace std;
const int M = 1000004;
const int INF = 0x3f3f3f3f;
int n, m;
struct Node
{
    int c,pos,next;
} E[M*4];
struct Sap
{
    int NE,NV,tot;
    int gap[M],dis[M],pre[M],head[M],cur[M];
    void init()
    {
        NE=0,tot=0;
        NV=m+1 + 1;
        memset(head, -1, sizeof(head));
    }
    int sap(int s,int t)
    {
        memset(dis,0,sizeof(int)*(NV+1));
        memset(gap,0,sizeof(int)*(NV+1));
        FF(i,NV) cur[i] = head[i];
        int u = pre[s] = s,maxflow = 0,aug =INF;
        gap[0] = NV;
        while(dis[s] < NV)
        {
    loop:
            for(int &i = cur[u]; i != -1; i = E[i].next)
            {
                int v = E[i].pos;
                if(E[i].c && dis[u] == dis[v] + 1)
                {
                    aug=min(aug,E[i].c);
                    pre[v] = u;
                    u = v;
                    if(v == t)
                    {
                        maxflow += aug;
                        for(u = pre[u]; v != s; v = u,u = pre[u])
                        {
                            E[cur[u]].c -= aug;
                            E[cur[u]^1].c += aug;
                        }
                        aug =INF;
                    }
                    goto loop;
                }
            }
            if( (--gap[dis[u]]) == 0)   break;
            int mindis = NV;
            for(int i = head[u]; i != -1 ; i = E[i].next)
            {
                int v = E[i].pos;
                if(E[i].c && mindis > dis[v])
                {
                    cur[u] = i;
                    mindis = dis[v];
                }
            }
            gap[ dis[u] = mindis+1 ] ++;
            u = pre[u];
        }
        return maxflow;
    }
    void AddEdge(int u,int v,int c )
    {
        E[NE].c = c;
        E[NE].pos = v;
        E[NE].next = head[u];
        head[u] = NE++;
        E[NE].c = 0;
        E[NE].pos = u;
        E[NE].next = head[v];
        head[v] = NE++;
    }
}sek;
int sum[100004];
int zsum;
int a[100004], b[100004], c[100004], d[100004];
int main()
{
    while(scanf("%d%d", &n, &m), (n||m))
    {
        memset(sum, 0, sizeof(sum));
        zsum = 0;
        sek.init();
        for(int i = 1;i <= m;i++)
        {
            int ls;
            scanf("%d", &ls);
            sek.AddEdge(0, i, ls);
            zsum += ls;
        }
        int k;
        scanf("%d", &k);
        for(int i = 1;i <= k;i++)
        {
            int q, w, e, r;
            scanf("%d%d%d%d", &q, &w, &e, &r);
            a[i] = q, b[i] = w, c[i] = e, d[i] = r;
            sum[c[i]] += r;
        }
        for(int i = 1;i <= k;i++)
        {
            for(int j = 1;j <= k;j++)
            {
                if(i != j)
                {
                    if(b[i] == a[j] && c[i] != c[j])
                    {
                        sek.AddEdge(c[i], c[j], INF);
                    }
                }
            }
        }
        for(int i = 1;i <= m;i++)
        {
            sek.AddEdge(i, m + 1, sum[i]);
        }
        printf("%d\n", zsum - sek.sap(0, m + 1));
    }
    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值