当前位置: 首页 > news >正文

模板ACM

最大费用最大流模板(注意和最小的区别仅仅是每条边cost取负,然后最后答案取负)


int n, m, u, S, T, Ans, cnt, Sum;
int dis[N], x, h[N], cur[N]; bool vis[N];
struct edge { int to, flow, cost, rev; };
vector <edge> G[N];
struct node {int x, dis;friend bool operator < (node a, node b) { return a.dis > b.dis; }
};void ins(int x, int y, int w, int l) {G[x].pb({y, w, -l, G[y].size()});                 // 最大费用最大流模板,这里要改成-l ,下面是+l,然后最后答案取负即可。G[y].pb({x, 0, l, G[x].size() - 1});
}
bool dij() {priority_queue <node> Q;F(i, 1, cnt) dis[i] = inf; dis[S] = 0; Q.push({S, 0});while (Q.size()) {node s = Q.top(); Q.pop();int k = s.x, v = s.dis;if (v > dis[k]) continue;for (auto e : G[k])if (e.flow && dis[e.to] > dis[k] + e.cost + h[k] - h[e.to]) {dis[e.to] = dis[k] + e.cost + h[k] - h[e.to];Q.push({e.to, dis[e.to]});}}return dis[T] < inf;
}
int DFS(int k, int flow) {if (k == T) return flow;int have = 0;vis[k] = 1;for (int &i = cur[k]; i < G[k].size(); i ++) {edge &e = G[k][i];if (!vis[e.to] && e.flow && dis[e.to] == dis[k] + e.cost + h[k] - h[e.to]) {int now = DFS(e.to, min(flow - have, e.flow));e.flow -= now, G[e.to][e.rev].flow += now;have += now;if (flow == have) break;}}vis[k] = 0;return have;
}map <int, int> H; int w[N];int calc(int x) {int ans = 0;for (int y = 2; y * y <= x; y ++)while (x % y == 0)x /= y, ans ++;ans += (x > 1);return ans;
}
void doit(int x) {if (!H[x]) {H[x] = ++ cnt;ins(cnt, T, 1, 0);w[cnt] = calc(x);}int v = H[x];ins(u, v, 1, w[u] - w[v]);
}int main() {
//    freopen("data.in","r",stdin);R(n), S = 1, T = cnt = 2;F(i, 1, n) {R(x);w[u = ++ cnt] = calc(x);ins(S, u, 1, 0);for (int j = 1; j * j <= x; j ++) {if (x % j == 0) {doit(j);if (j * j < x)doit(x / j);}}}//	scanf("%d%d%d%d", &n, &m, &S, &T);
//    F(i, 1, m) {
//        scanf("%d%d%d%d", &x, &y, &c, &w);
//        ins(x, y, c, w);
//    }Ans = 0;while (dij()) {F(i, 1, cnt) cur[i] = 0;int flow = DFS(S, inf);F(i, 1, cnt) h[i] += dis[i];Ans += h[T] * flow;}printf("%d\n", - Ans);
}

最大流:

#include <bits/stdc++.h>#define F(i, a, b) for (int i = (a); i <= (b); ++i)
#define G(i, a, b) for (int i = (a); i >= (b); --i)
#define mem(a, b) memset(a, b, sizeof a)
#define pb push_back
#define putc putchar
#define get getchar()
#define ll long long
#define V vector<int>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))using namespace std;template <typename Int>
void R(Int &x) {char c = get; x = 0; Int t = 1;for (; !isdigit(c); c = get) t = (c == '-' ? -1 : t);for (; isdigit(c); x = (x << 3) + (x << 1) + c - '0', c = get);x *= t;
}
template <typename Int>
void W(Int x) {if (x < 0) { putc('-'); x = -x; }if (x > 9) W(x / 10);putc(char(x % 10 + '0'));
}const int INF = 1e9;int n, m;
ll c, d;struct Edge { int to, rev, cap; };int N, S, T;
vector<vector<Edge>> Gg;
V levelv, cur;int add_edge(int u, int v, int cap) {Edge a{v, (int)Gg[v].size(), cap};Edge b{u, (int)Gg[u].size(), 0};Gg[u].pb(a);Gg[v].pb(b);return (int)Gg[u].size() - 1; // 返回 u 侧边下标,便于后续增容
}bool bfs() {fill(levelv.begin(), levelv.end(), -1);queue<int> Q;levelv[S] = 0; Q.push(S);while (!Q.empty()) {int u = Q.front(); Q.pop();for (auto &e : Gg[u]) if (e.cap > 0 && levelv[e.to] < 0) {levelv[e.to] = levelv[u] + 1;Q.push(e.to);}}return levelv[T] >= 0;
}int dfs(int u, int f) {if (u == T) return f;for (int &i = cur[u]; i < (int)Gg[u].size(); ++i) {Edge &e = Gg[u][i];if (e.cap > 0 && levelv[e.to] == levelv[u] + 1) {int ret = dfs(e.to, min(f, e.cap));if (ret > 0) {e.cap -= ret;Gg[e.to][e.rev].cap += ret;return ret;}}}return 0;
}// 在当前残量网络上尽量增广
int maxflow_once() {int flow = 0, aug;while (bfs()) {fill(cur.begin(), cur.end(), 0);while ((aug = dfs(S, INF)) > 0) flow += aug;}return flow;
}inline void RS(string &s) {s.clear();char c = get;while (isspace(c)) c = get;for (; !isspace(c); c = get) s.pb(c);
}int main() {// 输入R(n), R(m), R(c), R(d);vector<string> a(n);F(i, 0, n - 1) RS(a[i]);// 统计vector<int> rowCnt(n, 0), colCnt(m, 0);int E = 0;F(i, 0, n - 1) F(j, 0, m - 1)if (a[i][j] == '.') { ++rowCnt[i]; ++colCnt[j]; ++E; }int maxRow = 0, maxCol = 0;F(i, 0, n - 1) maxRow = max(maxRow, rowCnt[i]);F(j, 0, m - 1) maxCol = max(maxCol, colCnt[j]);int Delta = max(maxRow, maxCol);// 建图S = 0; T = n + m + 1; N = T + 1;Gg.assign(N, {});levelv.assign(N, -1);cur.assign(N, 0);// 记录源->行 与 列->汇 的边下标,便于逐步增容V s2r_idx(n), c2t_idx(m);// 源->行(初始容量0)F(i, 0, n - 1) s2r_idx[i] = add_edge(S, 1 + i, 0);// 行->列(空格子为1)F(i, 0, n - 1) F(j, 0, m - 1)if (a[i][j] == '.') add_edge(1 + i, 1 + n + j, 1);// 列->汇(初始容量0)F(j, 0, m - 1) c2t_idx[j] = add_edge(1 + n + j, T, 0);ll ans = (ll)4e18;const ll base = d * 1LL * E; // 常数项int totalFlow = 0;// k = 0 的代价ans = min(ans, base);// 逐步把每个行/列容量 +1,并在原残量网络上继续增广F(k, 1, Delta) {// 行、列容量 +1F(i, 0, n - 1) Gg[S][ s2r_idx[i] ].cap += 1;F(j, 0, m - 1) Gg[1 + n + j][ c2t_idx[j] ].cap += 1;totalFlow += maxflow_once(); // 新能多匹配多少就多送多少ll cost = base + (c * 1LL * k - d * 1LL * totalFlow);ans = min(ans, cost);if (totalFlow == E) break; // 已满匹配,后续只会让 cost 递增 c}W(ans), putc('\n');return 0;
}
http://www.dtcms.com/a/606338.html

相关文章:

  • 图论专题(二):“关系”的焦点——一眼找出「星型图的中心节点」
  • 宁晋网站开发2019做网站的出路
  • 食品招商网网站如何做好优化
  • 三、ingress全面详解: 实例配置及访问
  • 商丘三合一网站建设云南做网站费用
  • 用php做京东网站页面产品开发流程6个步骤
  • 北京网站seo推广上海有名的效果图公司
  • Windows下 AutoGen(二)Autogen Studio
  • 用别人公司名字做网站违法么中国建设招标网 官方网站下载
  • 2026中国(济南)国际化工装备与智能制造展览会将于3月9日举办
  • Linux入门攻坚——54、SCSI与iSCSI协议初步
  • 如何在需求文档不清导致返工后改进流程
  • 网站建设简运维 简历宣武深圳网站建设公司
  • 自己做相册的网站免费域名注册查询入口
  • 深圳企业网站建设费用楚雄 网站建设
  • 使用goaccess监控系统
  • Go语言使用的编译器 | 入门到实战全解析
  • 成都网站建设制作网络与智能媒体设计 干什么?
  • Flink 的 RocksDB 状态后端在 vivo 的实践
  • 5-脱氧-5-甲硫腺苷标记生物素,5-MTA-Biotin,Biotin-5-脱氧-5-甲硫腺苷,5-MTA-生物素复合物
  • 怎么做自己的网站免费进入公众号继续阅读下一章
  • fastapi项目结构
  • 家居网站建设方案wordpress 3.8下载
  • 一般网站建设需求有哪些方面找人注册公司需要多少钱
  • 聚焦Solana做多做空场景,XBIT以多维工具与合规架构筑牢交易价值根基
  • 数字货币的“iPhone时刻”:从概念到规模应用的挑战与突破路径
  • 备案时填写 网站内容图片类的wordpress
  • .net按地址动态调用VC++DLL将非托管DLL中的函数地址转换为.NET可调用的委托
  • 为什么要使用 .asStateFlow() 而不是直接赋值?
  • ICMP timestamp请求响应漏洞 处理