題目鏈結
題目大意:乙個\(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 的...