spoj1476 maximum profit,最大权闭合子图

http://www.spoj.com/problems/PROFIT/


最大权闭合子图:点权之和最大的闭合图。


建图:每一条有向边变为容量为inf,源S到正权点v( wv>0 )的边容量 wv ,负权点v( wv<0 )到汇 T 的边容量 wv ,零权点v( wv=0 )不与源和汇相连。然后求最小割(SUM-最大流)即为答案。

/*
 * Author: yew1eb
 * Created Time:  2014年10月31日 星期五 15时39分22秒
 * File Name: spoj1476 maximum profit.cpp
 */
#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int inf = 1e9;
const ll  INF = 1e18;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int maxn = 60010;
const int maxm = 2000010;

struct Edge {
    int to, cap, next;
    Edge(int _next=0,int _to=0,int _cap=0):next(_next),to(_to),cap(_cap) {}
} edge[maxm];

int n, m, S, T, cnt;
int head[maxn], tot;
int d[maxn];//到汇点的距离下界。
int gap[maxn];

void init()
{
    tot = 0;
    memset(head, -1, sizeof head );
}

void add(int u,int v,int c, int rc=0)
{
    edge[tot] = Edge(head[u], v, c);
    head[u] = tot++;
    edge[tot] = Edge(head[v], u, rc);
    head[v] = tot++;
}


int get_flow(int u, int flow)
{
    if(u==T || flow==0)return flow;
    int res=0, f;
    for(int i=head[u]; ~i; i=edge[i].next) {
        int &v = edge[i].to;
        if(d[u]>d[v] && (f=get_flow(v,min(flow,edge[i].cap)))>0) {
            edge[i].cap -= f;
            edge[i^1].cap += f;
            res += f;
            flow -= f;
            if(flow==0) return res;
        }
    }
    if(!(--gap[d[u]]))d[S]=cnt+2;
    gap[++d[u]]++;
    return res;
}

int isap()
{
    int flow = 0;
    memset(gap, 0, sizeof gap );
    memset(d, 0, sizeof d );
	cnt = T-S+1;
    gap[0] = cnt;
    while(d[S]<cnt) flow += get_flow(S, inf);
    return flow;
}


int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
   // freopen("out.cpp", "w", stdout);
#endif // ONLINE_JUDGE
	int t;
	int n, m;
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &n, &m);
		S = 0, T = n+m+1;
		int u, v, c;
		init();
		for(int i=1; i<=n; ++i){
			scanf("%d", &c);
			add(i, T, c);
		}
		int sum = 0;
		for(int i=n+1; i<=n+m; ++i){
			scanf("%d%d%d", &u, &v, &c);
			add(S, i, c);
			sum += c;
			add(i, u, inf);
			add(i, v, inf);
		}	
		int ans = sum - isap();
		printf("%d\n", ans);
	}
	return 0;
}





















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值