题意: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. 账号被盗!请勿在CSDN,回复不论什么消息。

    账号被盗!请勿在CSDN,回复不论什么消息.

  2. 修改SVN中文件的可执行属性

    博文来自下面路径,转载请注明原出处: http://bigwhite.blogbus.com/logs/74568031.html 修改SVN中文件的可执行属性 - [开源世界] Tag:开源世界 S ...

  3. HDU 1407 测试你是否和LTC水平一样高 枚举、二分、hash

    http://acm.hdu.edu.cn/showproblem.php?pid=1407 计算方程x^2+y^2+z^2= num的一个正整数解.num为不大于10000的正整数 思路: 方法一. ...

  4. 解决gvim 8.1中zip插件打开zip文件内容时,而文件路径带有空格的问题。

    解决gvim 8.1中zip插件打开zip文件内容时,而文件路径带有空格的问题. 现象是只能打开一次,第二次打开就显示为空了. 通过 lcd切换工作目录.使得命令行操作中不再有带空格的路径 vim81 ...

  5. jboss-as-7.1.1.Final与jdk1.8不兼容解决方案

    今天在安装1.8电脑上装了jboss7.1.1,配置好了运行的时候就是无法启动,最后得出答案是:jboss-as-7.1.1.Final与jdk1.8不兼容 1.如果你的电脑安装了jdk1.8,那么在 ...

  6. Android 获取签名证书的具体信息(Eclipse和Android studio通用)

    今天要用到签名证书的MD5,可是这个仅仅有在第一次生成的时候我看到了,这可怎么办呢,幸亏我们有google,我们执行以下的命令就OK了. keytool -list -v -keystore 签名证书 ...

  7. 撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)

    一:任务描写叙述 A,B两个进程通过管道通信,像曾经的互相聊天一样,然后A进程每次接收到的数据通过A1进程显示(一个新进程,用于显示A接收到的信息),A和A1间的数据传递採用共享内存,相应的有一个B1 ...

  8. 建立简单的服务器端程序 分类: B1_JAVA 2013-10-08 21:53 503人阅读 评论(0) 收藏

      参考自core java     package com.lujinhong.corejava; import java.io.IOException; import java.io.InputS ...

  9. spring mvc 解决csrf跨站请求攻击

    http://www.dewen.net.cn/q/935/spring+mvc+%E8%A7%A3%E5%86%B3csrf%E8%B7%A8%E7%AB%99%E8%AF%B7%E6%B1%82% ...

  10. [RxJSv& Javascript] forkJoin (reactive Promise.all) & Map

    forkJoin: When all observables complete emit the last value from each. productMap: Map<number, IP ...