题意:n(n <= 20)个项目,m(m <= 50)个技术问题,做完一个项目能够有收益profit (<= 1000),做完一个项目必须解决对应的技术问题,解决一个技术问题须要付出cost ( <= 1000),技术问题之间有先后依赖关系,求最大收益。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4971

——>>项目必须解决相应的技术问题,技术问题之间也存在依赖,相应闭合图,最大收益相应最大权和。。于是,最大权闭合图,最小割,最大流上场。。

建图:

1)超级源S = n + m, 超级汇T = n + m + 1

2)对于每一个项目i:S -> i (profit[i])

3)对于每一个技术问题i:i + n -> T (cost[i])

4)对于项目 i 必须解决的技术问题 j:i -> j + n (INF)

5)对于技术问题 j 必须先解决的技术问题
i: i + n -> j + n (INF) (这里我认为应为:j + n -> i + n (INF),这样理解才对,但是对不上例子,提交也WA。。)

然后,Dinic上场。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue> using std::queue;
using std::min; const int MAXN = 20 + 50 + 10;
const int MAXM = 20 + 1000 + 2500 + 50 + 10;
const int INF = 0x3f3f3f3f; int n, m, sum;
int hed[MAXN];
int cur[MAXN], h[MAXN];
int ecnt;
int S, T; struct EDGE
{
int to;
int cap;
int flow;
int nxt;
} edges[MAXM << 1]; void Init()
{
ecnt = 0;
memset(hed, -1, sizeof(hed));
sum = 0;
} void AddEdge(int u, int v, int cap)
{
edges[ecnt].to = v;
edges[ecnt].cap = cap;
edges[ecnt].flow = 0;
edges[ecnt].nxt = hed[u];
hed[u] = ecnt++;
edges[ecnt].to = u;
edges[ecnt].cap = 0;
edges[ecnt].flow = 0;
edges[ecnt].nxt = hed[v];
hed[v] = ecnt++;
} void Read()
{
int profit, cost, pc, tp; scanf("%d%d", &n, &m);
S = n + m;
T = n + m + 3;
for (int i = 0; i < n; ++i)
{
scanf("%d", &profit);
AddEdge(S, i, profit);
sum += profit;
}
for (int i = 0; i < m; ++i)
{
scanf("%d", &cost);
AddEdge(i + n, T, cost);
}
for (int i = 0; i < n; ++i)
{
scanf("%d", &pc);
for (int j = 0; j < pc; ++j)
{
scanf("%d", &tp);
AddEdge(i, tp + n, INF);
}
}
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < m; ++j)
{
scanf("%d", &tp);
if (tp)
{
AddEdge(i + n, j + n, INF);
}
}
}
} bool Bfs()
{
memset(h, -1, sizeof(h));
queue<int> qu;
qu.push(S);
h[S] = 0;
while (!qu.empty())
{
int u = qu.front();
qu.pop();
for (int e = hed[u]; e != -1; e = edges[e].nxt)
{
int v = edges[e].to;
if (h[v] == -1 && edges[e].cap > edges[e].flow)
{
h[v] = h[u] + 1;
qu.push(v);
}
}
} return h[T] != -1;
} int Dfs(int u, int cap)
{
if (u == T || cap == 0) return cap; int flow = 0, subFlow;
for (int e = cur[u]; e != -1; e = edges[e].nxt)
{
cur[u] = e;
int v = edges[e].to;
if (h[v] == h[u] + 1 && (subFlow = Dfs(v, min(cap, edges[e].cap - edges[e].flow))) > 0)
{
flow += subFlow;
edges[e].flow += subFlow;
edges[e ^ 1].flow -= subFlow;
cap -= subFlow;
if (cap == 0) break;
}
} return flow;
} int Dinic()
{
int maxFlow = 0; while (Bfs())
{
memcpy(cur, hed, sizeof(hed));
maxFlow += Dfs(S, INF);
} return maxFlow;
} int main()
{
int t, kase = 0; scanf("%d", &t);
while (t--)
{
Init();
Read();
printf("Case #%d: %d\n", ++kase, sum - Dinic());
} return 0;
}

hdu - 4971 - A simple brute force problem.(最大权闭合图)的更多相关文章

  1. HDU 4971 A simple brute force problem.

    A simple brute force problem. Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged o ...

  2. HDU 4971 - A simple brute force problem【最大权闭合图】

    有n(20)个工程,完成每个工程获得收益是p[i],m(50)个需要解决的难题,解决每个难题花费是c[i] 要完成第i个工程,需要先解决ki个问题,具体哪些问题,输入会给出 每个难题之间可能有依赖关系 ...

  3. 【最小割】HDU 4971 A simple brute force problem.

    说是最大权闭合图.... 比赛时没敢写.... 题意 一共同拥有n个任务,m个技术 完毕一个任务可盈利一些钱,学习一个技术要花费钱 完毕某个任务前须要先学习某几个技术 可是可能在学习一个任务前须要学习 ...

  4. HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4971 Description There's a company with several ...

  5. A simple brute force problem.

    hdu4971:http://acm.hdu.edu.cn/showproblem.php?pid=4971 题意:给你n个项目,每完成一个项目会有一定的收益,但是为了完成某个项目,要先学会一些技能, ...

  6. HDU5772 String problem 最大权闭合图+巧妙建图

    题意:自己看吧(不是很好说) 分析: 网络流:最大权闭合子图. 思路如下: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得 ...

  7. hdu 4972 A simple dynamic programming problem(高效)

    pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...

  8. HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)

    http://acm.hdu.edu.cn/showproblem.php?pid=3879 http://www.lydsy.com/JudgeOnline/problem.php?id=1497 ...

  9. hdu 3061 Battle 最大权闭合图

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3061 由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅.而他上任的第一天,就面对了一场极其困难的 ...

随机推荐

  1. [HTML] Change an HTML5 input's placeholder color with CSS

    We will look at what CSS selectors to use to change an HTML5 inputs placeholder color. This can diff ...

  2. hadoop的关键进程 分类: A1_HADOOP 2015-06-06 11:37 52人阅读 评论(0) 收藏

    hadoop集群中主要进程有 master:   NameNode, ResourceManager, slaves:   DataNode, NodeManager,  RunJar, MRAppM ...

  3. 任哲<<μC/OS>>

    从第二章开始啦: 程序控制块(TCB)  重要概念  相当于对应程序块的学生证,学号,,, 上面的图是一个简单的程序控制块,还会有复杂的程序控制块,也许是嵌套的两级的: 链表就相当于老师手中的花名册, ...

  4. 运行一个Hadoop Job所需要指定的属性 分类: A1_HADOOP 2015-02-02 21:33 231人阅读 评论(0) 收藏

    1.设置job的基础属性 Job job = new Job(); job.setJarByClass(***.class); job.setJobName("job name") ...

  5. phpstorm 2018本地激活

    这是简书上找到的,害怕以后找不到,记录一下网址为https://www.jianshu.com/p/133af2e4fe3f

  6. 认识PWA

    原文 简书原文:https://www.jianshu.com/p/f38f21ed45dc 大纲 前言 1.什么是PWA 2.PWA 应该具备的特点 3.PWA基础 4.构建 PWA 的业务场景 5 ...

  7. [Vue] Preload Data using Promises with Vue.js and Nuxt.js

    Nuxt.js allows you to return a Promise from your data function so that you can asynchronously resolv ...

  8. AngularJS之基本指令(init、repeat)

    <h3>ng-init初始化变量</h3> <div ng-init="name='aurora';age='18'"> <p ng-bi ...

  9. js实现计时功能

    原文链接:https://blog.csdn.net/qq_37936542/article/details/78912786 一:计时器功能 <!DOCTYPE html> <ht ...

  10. [SCSS] Organize Styles with SCSS Nesting and the Parent Selector

    SCSS nesting can produce DRYer code by targeting child elements without having to write the parent c ...