題解 AT1221 水筒

2022-05-07 21:18:12 字數 1511 閱讀 9506

題目鏈結

題目大意:乙個\(n \times m\)的矩陣裡有一些牆不能走,有一些建築物,有一些地方是原野。每走過一格原野需要消耗乙份水,建築物可以將水壺補滿。多次詢問從乙個建築物到另乙個建築物水壺容量至少為多少。

kruskal重構樹

分析:首先不難想到暴力,我們把所有可以相互到達的建築物兩兩連邊,如果我們要使得最大邊權盡量小那麼我們就要求最小生成樹。證明考慮貪心:不斷加邊直到兩點連通,這就是kruskal的過程。

求樹上兩點間邊權的最大值就是kruskal重構樹的板子題

但是如果我們暴力列舉所有建築物無法承受,但是我們發現有些邊是沒有用的,我們可以考慮類似於縮點的方法。我們給每個建築物乙個顏色,然後同一顏色的點離它最近的加油站都相同

這樣我們只需要列舉每個點以及和它相鄰的點,如果顏色不同連邊即可,這個可以在bfs的時候順便計算,染色發現已經染過的不同色點就連邊

#include #include #include #include #include using namespace std;

const int maxn = 2e3 + 100,maxp = 4e5 + 100,maxdep = 25;

int n,m,p,q,vis[maxn][maxn],dis[maxn][maxn],deltax = ,deltay = ;

namespace graph;

vectorg[maxp];

inline void addedge(int from,int to,int dist));}

int faz[maxp][maxdep + 1],dep[maxp],vis[maxp],col[maxp],val[maxp],col_tot;

inline void init(int u)

} inline void init()

inline int lca(int x,int y)

inline int query(int x,int y)

}namespace kruskal);}

int f[maxp],sz;

inline void init()

inline int find(int x)

inline void kruskal());

init();

int tot = p,lim = (p << 1) - 1;

for(int i = 1;i <= lim;i++)f[i] = i;

for(auto e : edges)

} }}inline bool check(int x,int y)

char mp[maxn][maxn];

struct posbuilding[maxp];

inline void bfs()

vis[nx][ny] = vis[x][y];

dis[nx][ny] = dis[x][y] + 1;

q.push(pos);

} }}int main()

題解 牛客 114514 水題

給你乙個長為n的序列 定義乙個序列下標的子集為先輩,當且僅當選出的這些下標對應的序列值的乘積為114514,而且因為只有乙隻野獸,所以有個要求是選出來的這些下標所對應的序列值最多有乙個1 請輸出有多少先輩 第一行乙個數表示n 之後一行n個數表示這個序列 n 229028,序列的值域在 0,11451...

P6022 快樂水 題解

同步 原題鏈結 簡要題意 一開始你有 n nn 瓶快樂水,每擁有1 11 瓶快樂水就可以附帶 n nn 個物件,第 i ii 個物件有了 a ia i ai 個就可以再獲得 1 11 瓶快樂水。不允許借代 賒賬,求最多得到的快樂水的瓶數,如果是無限多則輸出 inf text inf.這是洛谷一道月賽...

LOJ6303 水題 題解

題目來自loj。就記乙個公式,設f n,k 為n 裡分解得到的k k為質數 的個數,則f n,k f n k,k n k。證明很好證,顯然我們要的只有k,k 2,k 3 這樣的數有n k個,然後往下遞迴即可。至於k為合數,就質因數分解做就行。k的質因子最多o logk 個,遞迴顯然是o logn 的...