首页 > 其他 > 详细

Gold Mine 最大权闭合图

时间:2019-07-10 16:12:34      阅读:112      评论:0      收藏:0      [点我收藏+]

  题意:

有n个矿场   每个矿场有m个金矿  开采某个金矿有其 各自的 成本和收益  且开采某个金矿可能有开采 其他金矿的前提    一开始有无限钱  也就是不计成本  问最大收益是多少

 

为最大权闭合图的模板题 没啥好说的  数组开小了t了好几发。

技术分享图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f3f3f3f3f
const int N=3100;
const int M=5e6;

struct edge {
    int to, next;ll w;
} e[M << 1];
int head[N], cnt = 1;
void init()
{
    cnt=1;CLR(head,0);
}
void add(int x, int y, ll z) {
    e[++cnt] = (edge){y, head[x], z};
    head[x] = cnt;
    e[++cnt] = (edge){x, head[y], 0};
    head[y] = cnt;
}
int level[N];
bool bfs(int s, int t) {
    memset(level, 0, sizeof level);
    queue<int> q;
    level[s] = 1;
    q.push(s);
    while (!q.empty()) {
        int pos = q.front();
        q.pop();
        for (int i = head[pos]; i; i = e[i].next) {
            int nx = e[i].to;
            if (!e[i].w || level[nx]) continue;
            level[nx] = level[pos] + 1;
            q.push(nx);
        }
    }
    return level[t];
}
ll dfs(int s, int t, ll flow) {
    if (s == t) return flow;
    ll ret = 0;
    for (int i = head[s]; flow && i; i = e[i].next) {
        int nx = e[i].to;
        if (level[nx] == level[s] + 1 && e[i].w) {
            ll tmp = dfs(nx, t, min(flow, e[i].w));
            e[i].w -= tmp;
            e[i ^ 1].w += tmp;
            flow -= tmp;
            ret += tmp;
        }
    }
    if (!ret) level[s] = 0;
    return ret;
}
ll dinic(int s, int t) {
    ll ret = 0;
    while (bfs(s, t)) ret += dfs(s, t, inf);
    return ret;
}
int n,m,s,t,node[N],sum,cost[N],q,a,b;
void sol()
{
    init();
    ll sum=0;
    s=0,t=3000;
    RI(n);
    rep(i,1,n)
    {
        RI(m);
        rep(j,1,m)
        {
            RIII(a,b,q);
            b-=a;
            if(b>0)
            sum+=b,add(s,i*26+j,b);
            else
            add(i*26+j,t,-b);
            rep(k,1,q)
            {
                RII(a,b);add(i*26+j,a*26+b,inf);
            }
        }
    }
    printf("%lld\n",sum-dinic(s,t));
}
int main()
{
    int cas;RI(cas);
    rep(i,1,cas)printf("Case #%d: ",i),sol();
    return 0;
}
View Code

 

Gold Mine 最大权闭合图

原文:https://www.cnblogs.com/bxd123/p/11164491.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!