日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[BZOJ3206][Apio2013]道路费用

發布時間:2025/4/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [BZOJ3206][Apio2013]道路费用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[BZOJ3206][Apio2013]道路費用

試題描述

輸入

第一行包含三個由空格隔開的整數N,M和K。接下來的 M行描述最開始的M 條道路。這M行中的第i行包含由空格隔開的整數ai,bi和c i,表示有一條在a i和b i之間,費用為c i的雙向道路。接下來的K行描述新建的K條道路。這 K行中的第i行包含由空格隔開的整數 xi和yi,表示有一條連接城鎮xi和yi新道路。最后一行包含N個由空格隔開的整數,其中的第j個為pj,表示從城鎮j 前往城鎮 1的人數。輸入也滿足以下約束條件。1 ≤ N ≤ 100000;1 ≤ K ≤ 20;1 ≤ M ≤ 300000;對每個i和j,1 ≤ ci, pj ≤ 10^6;

輸出

你的程序必須輸出恰好一個整數到標準輸出,表示能獲得的最大的收入。

輸入示例

5 5 1 3 5 2 1 2 3 2 3 5 2 4 4 4 3 6 1 3 10 20 30 40 50

輸出示例

400

數據規模及約定

見“輸入

題解

先強制 K 條邊都選,即把它們先都放到圖里。那么現在如果圖是不連通的,我們就需要按邊權從小到大依次往里加入那 M 條邊直到聯通,那么這一步中我加入的邊是所有方案中都必選的邊。

接下來,把圖中的邊清空,加入必選邊,連通塊縮成點,這樣我們會得到一個點數不超過 K + 1 的圖,令此圖為新圖(注意,新圖中不包含任何邊,只有那至多?K + 1 個點),同時 M 條邊中必選邊之外的邊如果放在新圖中會有很多重邊,將這些重邊合并,于是壓縮成了最多 K2 條邊。然后我們二進制枚舉 K 條邊是否選取,對于一個必選的屬于 Mr.Greedy 的邊的集合 S,在新圖中加入集合 S 中的所有邊,如果圖不連通,我們就需要用那 K2 條邊中的某些邊連通整個圖(令這些邊為K2必選邊);重新在新圖中加入K2必選邊,連通塊縮點后加入集合 S 中的邊我們就得到了一棵只包含 S 中的邊的樹;那么再依次找 K2?里非必選的邊(記得重標號,因為剛剛又縮了一次點),對于一條這樣的邊 (u, v),在樹上路徑 (u, v) 上所有邊的權值的最大值需要和這條邊 (u, v) 的權值取 min。

還是貼代碼吧。。。。。

#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> using namespace std;int read() {int x = 0, f = 1; char c = getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }return x * f; }#define maxn 100010 #define maxk 25 #define maxm 300010 #define oo 2147483647 #define LL long longint n, K, M, Peo[maxn];struct Edge {int u, v, w;Edge() {}Edge(int _1, int _2, int _3): u(_1), v(_2), w(_3) {}bool operator < (const Edge& t) const { return w < t.w; } } es[maxm], ek_own[maxk], ek[maxk*maxk]; bool used[maxm]; int K_id[maxn], G[maxk][maxk]; LL siz[maxk], reas[maxk];int fa[maxn]; int findset(int x) { return x == fa[x] ? x : fa[x] = findset(fa[x]); }int m, head[maxk], nxt[maxk<<1], to[maxk<<1], eid[maxk<<1]; void AddEdge(int a, int b, int c) {to[++m] = b; eid[m] = c; nxt[m] = head[a]; head[a] = m;swap(a, b);to[++m] = b; eid[m] = c; nxt[m] = head[a]; head[a] = m;return ; }int S[maxk], top; bool dfs(int u, int pa, int s, int t, int w) {if(u == t) {int U = findset(s);for(int i = 1; i <= top; i++) {ek_own[eid[S[i]]].w = min(ek_own[eid[S[i]]].w, w); // printf("update %d: %d\n", eid[S[i]], w);s = to[S[i]];fa[findset(s)] = U;}return 1;}for(int e = head[u]; e; e = nxt[e]) if(to[e] != pa) {S[++top] = e;if(dfs(to[e], u, s, t, w)) return 1;top--;}return 0; }LL trs[maxk], ans, tmp; void build(int u, int pa) {trs[u] = reas[u];for(int e = head[u]; e; e = nxt[e]) if(to[e] != pa) {build(to[e], u);trs[u] += trs[to[e]]; // printf("trs: %lld\n", trs[to[e]]);tmp += trs[to[e]] * ek_own[eid[e]].w;}return ; }int main() { // freopen("data.in", "r", stdin);n = read(); M = read(); K = read();for(int i = 1; i <= M; i++) {int a = read(), b = read(), c = read();es[i] = Edge(a, b, c);}for(int i = 1; i <= n; i++) fa[i] = i;for(int i = 1; i <= K; i++) {int a = read(), b = read();ek_own[i] = Edge(a, b, oo);int U = findset(a), V = findset(b);if(U != V) fa[V] = U;}for(int i = 1; i <= n; i++) Peo[i] = read();sort(es + 1, es + M + 1);for(int i = 1; i <= M; i++) {Edge& e = es[i];int U = findset(e.u), V = findset(e.v);if(U != V) used[i] = 1, fa[V] = U;}for(int i = 1; i <= n; i++) fa[i] = i;for(int i = 1; i <= M; i++) if(used[i]) fa[findset(es[i].v)] = findset(es[i].u);// above: get K connected_blockint cntk = 0;for(int i = 1; i <= n; i++) {int u = findset(i);if(!K_id[u]) K_id[u] = ++cntk;siz[K_id[i] = K_id[u]] += Peo[i];}// above: get connected_block's idfor(int i = 1; i <= K; i++) {Edge& e = ek_own[i];e.u = K_id[e.u]; e.v = K_id[e.v];}for(int i = 1; i <= cntk; i++)for(int j = 1; j <= cntk; j++) G[i][j] = oo;for(int i = 1; i <= M; i++) if(!used[i]) {Edge& e = es[i];int u = K_id[e.u], v = K_id[e.v];G[u][v] = G[v][u] = min(G[u][v], e.w);}int cek = 0;for(int i = 1; i <= cntk; i++)for(int j = i + 1; j <= cntk; j++) if(G[i][j] < oo)ek[++cek] = Edge(i, j, G[i][j]);sort(ek + 1, ek + cek + 1);// above: get prepared, ek means edges which don't belong to Mr.Greedy/*for(int i = 1; i <= n; i++) printf("%d%c", K_id[i], i < n ? ' ' : '\n');for(int i = 1; i <= cntk; i++) printf("%lld%c", siz[i], i < cntk ? ' ' : '\n');for(int i = 1; i <= cek; i++) printf("%d %d: %d\n", ek[i].u, ek[i].v, ek[i].w); // */int all = (1 << K) - 1;for(int S = 0; S <= all; S++) { // printf("here %d %d %d\n", cntk, K, cek);for(int i = 1; i <= cntk; i++) fa[i] = i;bool ok = 1;for(int i = 1; i <= K; i++) if(S >> i - 1 & 1) {Edge& e = ek_own[i];int U = findset(e.u), V = findset(e.v);if(U == V){ ok = 0; break; }fa[V] = U;}if(!ok) continue;for(int i = 1; i <= cek; i++) used[i] = 0;for(int i = 1; i <= cek; i++) {Edge& e = ek[i];int U = findset(e.u), V = findset(e.v);if(U != V) used[i] = 1, fa[V] = U;}for(int i = 1; i <= cntk; i++) fa[i] = i;for(int i = 1; i <= cek; i++) if(used[i]) fa[findset(ek[i].v)] = findset(ek[i].u);int cntn = 0;for(int i = 1; i <= cntk; i++) K_id[i] = reas[i] = 0;for(int i = 1; i <= cntk; i++) {int u = findset(i);if(!K_id[u]) K_id[u] = ++cntn;reas[K_id[i] = K_id[u]] += siz[i];} // printf("trs: "); for(int i = 1; i <= cntn; i++) printf("%lld%c", reas[i], i < cntn ? ' ' : '\n');m = 0; memset(head, 0, sizeof(head));for(int i = 1; i <= K; i++) if(S >> i - 1 & 1) {Edge& e = ek_own[i]; e.w = oo;AddEdge(K_id[e.u], K_id[e.v], i);} // printf("here2 %d %d\n", cntn, m);for(int i = 1; i <= cntn; i++) fa[i] = i;for(int i = 1; i <= cek; i++) if(!used[i]) {Edge e = Edge(K_id[ek[i].u], K_id[ek[i].v], ek[i].w);int U = findset(e.u), V = findset(e.v);if(U != V) top = 0, dfs(e.u, 0, e.u, e.v, e.w);}tmp = 0;build(1, 0); // printf("tmp: %lld\n", tmp);ans = max(ans, tmp);}printf("%lld\n", ans);return 0; }

我都要寫吐了。。。。。

轉載于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6814959.html

總結

以上是生活随笔為你收集整理的[BZOJ3206][Apio2013]道路费用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: julia一区二区 | 夜色资源网 | 90岁肥老奶奶毛毛外套 | 成人国产精品蜜柚视频 | 体感预报日剧 | 91精品国产色综合久久不卡电影 | 欧美日韩成人网 | 亚洲精品在线观看视频 | 日韩女优在线视频 | 国产乱码一区二区三区在线观看 | 最新版天堂资源在线 | 国产成人精品无码片区在线 | 国产三级在线观看视频 | 双性娇喘浑圆奶水h男男漫画 | 男生女生羞羞网站 | 777久久久精品一区二区三区 | av777777| 亚洲色图 美腿丝袜 | 黄色亚洲精品 | 男女做爰猛烈吃奶啪啪喷水网站 | 新呦u视频一区二区 | 日本黄色一级网站 | 一级片手机在线观看 | 久久久国产精品免费 | 黄色片子视频 | 韩国三级做爰高潮 | 国产小视频在线免费观看 | 国产性生活片 | 人妻无码中文字幕 | 中文字幕+乱码+中文字幕明步 | 国产视频一区二区不卡 | 男男全肉变态重口高h | 久久久久五月天 | 日本艳妇 | 中文在线观看高清视频 | 成年黄色网 | 色亚洲天堂 | 我和公激情中文字幕 | 夜色福利 | 亚洲一区二区三区四区在线播放 | 人人澡人人澡 | 久久成人精品视频 | 女同性恋一区二区三区 | 精品人妻在线播放 | 国产精品一区二区入口九绯色 | 久久午夜无码鲁丝片午夜精品 | 国产一区二区三区在线免费 | 91在线观看. | 亚洲成人另类 | 日本一本二本三区免费 | 日韩精品一区二区三区无码专区 | 久久影音 | 极品三级 | 住在隔壁的她动漫免费观看全集下载 | 欧美人妻日韩精品 | 成人黄色激情视频 | 国产欧美日韩综合 | 女同激情久久av久久 | 国产一二三精品 | 国产免费av电影 | 999视频 | 大乳丰满人妻中文字幕日本 | 鲁丝片一区二区三区 | 青青视频免费观看 | 国内老熟妇对白hdxxxx | 色www情 | 伊人亚洲精品 | 日韩网站免费观看 | 88av.com | 99riav1国产精品视频 | 女人性做爰24姿势视频 | 一本一道久久a久久综合蜜桃 | 国产精品99久久久久久www | 久久影视大全 | 午夜性生活片 | 亚洲网站视频 | 97看片吧 | 第四色在线视频 | 深夜福利一区二区三区 | 国产精品免费看片 | 日韩精品中文字 | 久草毛片 | 想要视频在线 | 在线爱情大片免费观看大全 | 日本内谢少妇xxxxx少交 | 国产午夜精品久久久久久久 | 国产日韩二区 | 99爱视频在线 | 欧美中文字幕在线 | 久久久久久久中文字幕 | av网在线 | 欧美在线观看视频 | 国产精品一区二区在线免费观看 | 国产小视频免费 | 伊人久久视频 | 国产a国产 | 伊人网站在线观看 | 中国一级特黄毛片 | 国产精品黄色 |