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

题意:游戏王同调召唤的方法,每只怪兽有等级和攻击力,两种不同类型的怪兽可以在一定限制下召唤出某一怪兽,具体限制要求可以参照题面

思路:先在那些限制要求下预处理出两种类型怪兽组合所能召唤出的那些怪兽,可以建二分图,对于两只怪兽攻击力计算有两种选择,可以相加计算攻击力,也可以组合新怪兽计算攻击力,所以可以按以下方式建图:

1.所有边容量均为1,源点向左部点连边费用为0,向右部点连边费用为该点攻击力,然后左部点向汇点连边费用为该点攻击力,向右部点连边费用为组合怪兽攻击力,右部点再向汇点连边费用为0,这样基于流量的限制,就可以使攻击力的两种计算方法体现出来了

2.所有边容量还是1,只有当组合的怪兽攻击力大于两怪兽累加和时才建边,费用为攻击力之差,源点到左部点连边费用为0,右部点向汇点连边连边费用为0,最后加上基础攻击力即可

注意因为求的是最大费用所以费用需为负,而且在跑费用流时,当费用变大时就停止答案的更新或者结束费用流

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <climits>
#include <functional>
#include <deque>
#include <ctime>#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int MAXN = 1000;
const int MAXM = 500000;
const int INF = 0x3f3f3f3f;typedef long long ll;int res;struct Edge
{int from, to, next, cap, flow, cost;
} edge[MAXM];int head[MAXN], tol;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N;//节点总个数,节点编号从0~N-1void init(int n)
{N = n;tol = 0;memset(head, -1, sizeof(head));
}void addedge(int u, int v, int cap, int cost)
{edge[tol].from = u;edge[tol].to = v;edge[tol].cap = cap;edge[tol].cost = cost;edge[tol].flow = 0;edge[tol].next = head[u];head[u] = tol++;edge[tol].from = v;edge[tol].to = u;edge[tol].cap = 0;edge[tol].cost = -cost;edge[tol].flow = 0;edge[tol].next = head[v];head[v] = tol++;
}bool spfa(int s, int t)
{queue<int>q;for (int i = 0; i < N; i++){dis[i] = INF;vis[i] = false;pre[i] = -1;}dis[s] = 0;vis[s] = true;q.push(s);while (!q.empty()){int u = q.front();q.pop();vis[u] = false;for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap > edge[i].flow &&dis[v] > dis[u] + edge[i].cost ){dis[v] = dis[u] + edge[i].cost;pre[v] = i;if (!vis[v]){vis[v] = true;q.push(v);}}}}if (pre[t] == -1) return false;else return true;
}//返回的是最大流,cost存的是最小费用
int minCostMaxflow(int s, int t, int &cost)
{int flow = 0;cost = 0;while (spfa(s, t)){int Min = INF;for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){if (Min > edge[i].cap - edge[i].flow)Min = edge[i].cap - edge[i].flow;}for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){edge[i].flow += Min;edge[i ^ 1].flow -= Min;cost += edge[i].cost * Min;//printf("**********%d %d\n", Min, cost);}res = min(cost, res);flow += Min;}return flow;
}struct monster
{int lev, atk;monster(int lev = 0, int atk = 0) : lev(lev), atk(atk) {}
};vector <monster> g[2];
int gra[MAXN][MAXN], type[MAXN], id[MAXN];int main()
{int tt;scanf("%d", &tt);while (tt--){memset(gra, 0, sizeof(gra));g[0].clear(), g[1].clear();int n, m;scanf("%d%d", &n, &m);int cl = 0, cr = 0;for (int i = 1; i <= n; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);if (a == 0)id[i] = cl++;elseid[i] = cr++;type[i] = a;g[a].push_back(monster(b, c));}for (int i = 1; i <= m; i++){int lev, atk, sum;scanf("%d%d%d", &lev, &atk, &sum);if (sum == 0){for (int j = 0; j < cl; j++)for (int k = 0; k < cr; k++)if (g[0][j].lev + g[1][k].lev == lev)gra[j][k] = max(gra[j][k], atk);}else if (sum == 1){int x;scanf("%d", &x);if (type[x] == 0){for (int k = 0; k < cr; k++)if (g[0][id[x]].lev + g[1][k].lev == lev)gra[id[x]][k] = max(gra[id[x]][k], atk);}else{for (int j = 0; j < cl; j++)if (g[0][j].lev + g[1][id[x]].lev == lev)gra[j][id[x]] = max(gra[j][id[x]], atk);}}else{int x, y;scanf("%d%d", &x, &y);if (type[x] == 1) swap(x, y);if (g[0][id[x]].lev + g[1][id[y]].lev == lev){gra[id[x]][id[y]] = max(gra[id[x]][id[y]], atk);}}}// for (int i = 0; i < cl; i++)// {//     for (int j = 0; j < cr; j++)//         printf("%d ", gra[i][j]);//     printf("\n");// }int s = cl + cr, t = s + 1;init(t + 1);for (int i = 0; i < cl; i++)for (int j = 0; j < cr; j++)if (gra[i][j] > 0)addedge(i, j + cl, 1, -gra[i][j]);for (int i = 0; i < cl; i++){addedge(s, i, 1, 0);addedge(i, t, 1, -g[0][i].atk);}for (int i = 0; i < cr; i++){addedge(s, i + cl, 1, -g[1][i].atk);addedge(i + cl, t, 1, 0);}//        for(int i = 0; i < tol; i++)
//            printf("%d %d %d %d\n", edge[i].from, edge[i].to, edge[i].cap, edge[i].cost);int ans;res = INF;minCostMaxflow(s, t, ans);printf("%d\n", -res);}return 0;
}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <climits>
#include <functional>
#include <deque>
#include <ctime>#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int MAXN = 1000;
const int MAXM = 1001000;
const int INF = 0x3f3f3f3f;typedef long long ll;int res;struct Edge
{int from, to, next, cap, flow, cost;
} edge[MAXM];int head[MAXN], tol;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N;//节点总个数,节点编号从0~N-1void init(int n)
{N = n;tol = 0;memset(head, -1, sizeof(head));
}void addedge(int u, int v, int cap, int cost)
{edge[tol].from = u;edge[tol].to = v;edge[tol].cap = cap;edge[tol].cost = cost;edge[tol].flow = 0;edge[tol].next = head[u];head[u] = tol++;edge[tol].from = v;edge[tol].to = u;edge[tol].cap = 0;edge[tol].cost = -cost;edge[tol].flow = 0;edge[tol].next = head[v];head[v] = tol++;
}bool spfa(int s, int t)
{queue<int>q;for (int i = 0; i < N; i++){dis[i] = INF;vis[i] = false;pre[i] = -1;}dis[s] = 0;vis[s] = true;q.push(s);while (!q.empty()){int u = q.front();q.pop();vis[u] = false;for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap > edge[i].flow &&dis[v] > dis[u] + edge[i].cost ){dis[v] = dis[u] + edge[i].cost;pre[v] = i;if (!vis[v]){vis[v] = true;q.push(v);}}}}if (pre[t] == -1) return false;else return true;
}//返回的是最大流,cost存的是最小费用
int minCostMaxflow(int s, int t, int &cost)
{int flow = 0;cost = 0;while (spfa(s, t)){int Min = INF;for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){if (Min > edge[i].cap - edge[i].flow)Min = edge[i].cap - edge[i].flow;}for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){edge[i].flow += Min;edge[i ^ 1].flow -= Min;cost += edge[i].cost * Min;}res = min(cost, res);flow += Min;}return flow;
}struct monster
{int lev, atk;monster(int lev = 0, int atk = 0) : lev(lev), atk(atk) {}
};vector <monster> g[2];
int gra[MAXN][MAXN], type[MAXN], id[MAXN];int main()
{int tt;scanf("%d", &tt);while (tt--){memset(gra, 0, sizeof(gra));g[0].clear(), g[1].clear();int n, m;scanf("%d%d", &n, &m);int cl = 0, cr = 0, sum = 0;for (int i = 1; i <= n; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);if (a == 0)id[i] = cl++;elseid[i] = cr++;sum += c;type[i] = a;g[a].push_back(monster(b, c));}for (int i = 1; i <= m; i++){int lev, atk, sum;scanf("%d%d%d", &lev, &atk, &sum);if (sum == 0){for (int j = 0; j < cl; j++)for (int k = 0; k < cr; k++)if (g[0][j].lev + g[1][k].lev == lev)gra[j][k] = max(gra[j][k], atk);}else if (sum == 1){int x;scanf("%d", &x);if (type[x] == 0){for (int k = 0; k < cr; k++)if (g[0][id[x]].lev + g[1][k].lev == lev)gra[id[x]][k] = max(gra[id[x]][k], atk);}else{for (int j = 0; j < cl; j++)if (g[0][j].lev + g[1][id[x]].lev == lev)gra[j][id[x]] = max(gra[j][id[x]], atk);}}else{int x, y;scanf("%d%d", &x, &y);if (type[x] == 1) swap(x, y);if (g[0][id[x]].lev + g[1][id[y]].lev == lev){gra[id[x]][id[y]] = max(gra[id[x]][id[y]], atk);}}}// for (int i = 0; i < cl; i++)// {//  for (int j = 0; j < cr; j++)//      printf("%d ", gra[i][j]);//  printf("\n");// }int s = cl + cr, t = s + 1;init(t + 1);for (int i = 0; i < cl; i++)for (int j = 0; j < cr; j++)if (gra[i][j] > 0 && gra[i][j] > g[0][i].atk + g[1][j].atk)addedge(i, j + cl, INF, g[0][i].atk + g[1][j].atk - gra[i][j]);for (int i = 0; i < cl; i++){addedge(s, i, 1, 0);//  addedge(i, t, 1, -g[0][i].atk);}for (int i = 0; i < cr; i++){//  addedge(s, i + cl, 1, -g[1][i].atk);addedge(i + cl, t, 1, 0);}int ans;res = 0;minCostMaxflow(s, t, ans);printf("%d\n", sum - res);}return 0;
}

HDU 5383 Yu-Gi-Oh!(费用流)相关推荐

  1. HDU 2282 Chocolate (最小费用最大流)

    HDU  2282 Chocolate (最小费用最大流) #include <iostream> #include <cstdio> #include <queue&g ...

  2. hdu 2448 Mining Station on the Sea(最短路+费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2448 题意:给你一个由N个港口和M个海上油田构成的连通无向图(给出了图中所有的边和权值),现在给你N个 ...

  3. hdu 3395(费用流,二分图的最大权匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3395 解题思路: 这个构图很容易出错,最开始都容易想,把每个点拆开,分为攻击和被攻击的,建图如下: 源 ...

  4. HDU Problem - 1533 Going Home(费用流板子题)

    题目链接 Problem Description On a grid map there are n little men and n houses. In each unit time, every ...

  5. HDU 4833 Best Financing 一脸费用流的dp

    原题:http://acm.hdu.edu.cn/showproblem.php?pid=4833 题意:中文题不解释... 解题思路: 首先以interest_rates为费用建图跑费用流是比较容易 ...

  6. HDU 3618 Good Plan(费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3618 Problem Description FJ has two same houses for r ...

  7. HDU 1533 费用流入门

    费用流 (最小费用最大流) 网络图中 每条边 多给出了 单位流量的费用 cost(u,v) ,当通过(u,v)的流量为f(u,v)f(u,v)f(u,v)时,需要花费 f(u,v)∗cost(u,v) ...

  8. POJ 2135 Farm Tour amp;amp; HDU 2686 Matrix amp;amp; HDU 3376 Matrix Again 费用流求来回最短路...

    累了就要写题解,近期总是被虐到没脾气. 来回最短路问题貌似也能够用DP来搞.只是拿费用流还是非常方便的. 能够转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1.然后连 ...

  9. hdu 5045 费用流

    题意:      网选赛的一个题目,当时各种超时各种wa,哎! 题意是有n个人m道题,每个人对每道题都有一个ac率,每相邻的n到题目必须n个人每人一道,顺序无所谓,上下的m%n道只要不出现一个人做两道 ...

最新文章

  1. 【Android UI设计与开发】第02期:引导界面(二)使用ViewPager实现欢迎引导页面
  2. Navicat 使用sql命令建数据库和表详细过程_2
  3. VS2015 error LNK2019 无法解析的外部符号 _WinMain@16,该符号在函数 int __cdecl invoke_main(void)
  4. java List 排序 Collections.sort() 对 List 排序
  5. 20应用统计考研复试要点(part39)--概率论与数理统计
  6. RUNOOB python练习题25 递归实现阶乘
  7. a76比a73强多少_arm的a73和a72同上10nm,谁强?
  8. C++学习之路 | PTA乙级—— 1071 小赌怡情 (15 分)(精简)
  9. vue 表格中有列需要异步加载_Vue中使用async/await解决异步请求问题
  10. 操作系统可实训可练习的项目
  11. 前端实现街道地图_来自法国的注重保护个人隐私的开源地图
  12. Python3网络爬虫(九):使用Selenium爬取百度文库word文章
  13. 华为digix算法大赛2020机器学习赛道-搜索相关性初赛A/B榜rank1
  14. (八十三)第三方类库不支持64位处理器的解决方法
  15. 比较计算机动画与传统动画的异同,定格动画和传统动画有什么区别?基本一样吧?...
  16. java vcard格式_关于vcard 文件数据格式,以备不时之需
  17. C语言 计算BMI值,建议体重
  18. 07_Flask闪现 get_flashed_messages()
  19. 简书收入结算与提现常见问题
  20. groupadd: cannot open /etc/group

热门文章

  1. word文档图标变成白纸_word图标变了_word图标变成白底方框
  2. unity python热更新_Unity热更新介绍和测试方法
  3. 基于ngc的cuda镜像封装TensorFlow 实例
  4. 系统分析师-2021年下午简答题
  5. 想知道吗?CTO 比普通程序员强在哪?
  6. 零基础学平面设计怎么掌握好基础
  7. SPSS(十九)SPSS之时间序列模型(图文+数据集)
  8. 论文图片格式要求具体有哪些?
  9. s型增长的matlab曲线图,matlab拟合s型曲线
  10. WIN8 与WIN7的64位及32位 分别对Legacy BIOS+MBR和UEFI+GPT两种启动方式和分区架构下的安装可行性分析