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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

codevs 1218 疫情控制

發布時間:2023/12/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 codevs 1218 疫情控制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:

一棵有n個點的樹,樹上有m個障礙在給定的位置,現在需要移動這m個障礙,使得從根節點出發的任意路徑不能到達任意一個葉子節點(不能放在根節點上),求移動的最小花費。

?

題解:

首先需要明白的有這幾點:

① 如果一個點所有的兒子都被阻礙了,那么這個點也會被阻礙,那么現在的問題就是覆蓋根所有的兒子節點。

② 若在規定的時間移動這m個點,那么這m個點越往上移動越優越。

③ 若在規定的時間移動這m個點,那么一定會出現兩種情況,第一種不能越過根節點,第二種能夠越過根節點。

?

現在需要解決一下問題:

1.怎么解決規定的時間,可以二分一個時間。

2.怎么在很小的復雜度使得m個點盡量的往上跳,倍增

3.怎么處理那兩種情況?

  首先處理不能越過根節點的情況,盡量的往上跳,把到達極限的點標記,然后將所有的標記根據①的原理上傳到根的兒子。

  然后處理能夠越過根節點的情況,記錄下每個能夠越過根節點的點剩余的時間 t 和屬于哪條路徑的根的兒子的編號 id,記錄下需要被其他路徑的點覆蓋的根的兒子的編號,然后貪心覆蓋就好了。。。

?

代碼:

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std;const int N = 5e4 + 7; struct edge {int v, nxt, w;}e[N<<1]; struct node {int w, id;} g[N], f[N]; int anc[20][N], cos[20][N], ecnt, head[N], vis[N], n, m, army[N];void adde (int u, int v, int w) {e[ecnt].v = v;e[ecnt].w = w;e[ecnt].nxt = head[u];head[u] = ecnt++; }void DFS (int u, int pre) {for (int it = head[u]; it != -1; it = e[it].nxt) {int v = e[it].v;if (v == pre) continue;anc[0][v] = u;cos[0][v] = e[it].w;for (int i = 1; i <= 18; ++i) {anc[i][v] = anc[i-1][anc[i-1][v]];cos[i][v] = cos[i-1][v] + cos[i-1][anc[i-1][v]];}DFS(v, u);} }bool cmp (node a, node b) {return a.w < b.w;}void pushup (int u, int pre) {int isleaf = 1, flag = 1;for (int it = head[u]; it != -1; it = e[it].nxt) {int v = e[it].v;if (v == pre) continue;pushup(v, u);if (!vis[v]) flag = 0;isleaf = 0;}if (flag && !isleaf && u != 1) vis[u] = 1; }int check (int x) {int cntg = 0, cntf = 0;memset (vis, 0, sizeof vis);for (int i = 1; i <= m; ++i) {int p = army[i], t = x;for (int j = 18; j >= 0; --j) {if (anc[j][p] && t >= cos[j][p]) {t -= cos[j][p];p = anc[j][p];}}if (p == 1) {p = army[i];for (int j = 18; j >= 0; --j)if (anc[j][p] > 1) p = anc[j][p];g[++cntg] = (node){t, p};}else vis[p] = 1;}pushup(1, 0);for (int it = head[1]; it != -1; it = e[it].nxt) {int v = e[it].v;if (!vis[v]) f[++cntf] = (node){e[it].w, v};}sort (g + 1, g + 1 + cntg, cmp);sort (f + 1, f + 1 + cntf, cmp);int cur = 1;f[cntf+1] = (node){1e9 + 7, 0};for (int i = 1; i <= cntg; ++i) {if (!vis[g[i].id]) vis[g[i].id] = 1;else if (g[i].w >= f[cur].w) vis[f[cur].id] = 1;while (vis[f[cur].id]) cur++;}return cur > cntf; }int main () {memset (head, -1, sizeof head);scanf ("%d", &n);for (int i = 1; i < n; ++i) {int u, v, w;scanf ("%d%d%d", &u, &v, &w);adde (u, v, w);adde (v, u, w);}DFS (1, 0);scanf ("%d", &m);for (int i = 1; i <= m; ++i) scanf ("%d", &army[i]);int l = 0, r = 1e9 + 7;while (l < r) {int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}if (l == 1e9 + 7) puts("-1");else printf ("%d\n", l);return 0; }

  

總結:

遇到問題不要慌張~慢慢分析,首先不要考慮復雜度,直接嘴炮,然后慢慢進行算法上的優化。。。

?

轉載于:https://www.cnblogs.com/xgtao/p/5984858.html

總結

以上是生活随笔為你收集整理的codevs 1218 疫情控制的全部內容,希望文章能夠幫你解決所遇到的問題。

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