顯然的是,不同的生成樹的不同權值的邊數一定是一樣的
我們可以先跑一遍kruskal把每種邊需要多少條記錄一下
然後由於相同權值的邊不超過10條,所以在相同權值的邊內部搜一下,看哪些邊加進原圖無環
然後乘法原理和前面的答案乘一下
不同的選擇方法對後面的並查集的更新肯定是沒有影響的,不然一開始的kruskal不會這樣選邊
所以可以隨便選一組邊加入並查集,然後繼續做後面的權值
注意由於要回溯,所以並查集不能路徑壓縮,為了保證效率最好寫乙個按秩合併
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ll long long
#define lb long double
#define x first
#define y second
#define pair pair#define pb push_back
#define pf push_front
#define mp make_pair
#define lowbit(x) x & (-x)
using namespace std;
const int mod=31011;
const ll linf=2e16;
const int inf=2e9;
const int magic=348;
const double eps=1e-10;
inline int getint()
if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
while (isdigit(ch=getchar())) res=res*10+ch-'0';
return f?res:-res;
}int n,e;
int pre[148],rnk[148];
inline int find_anc(int x)
inline pair update(int x,int y)
return mp(x,0);
} else }
struct edge
edge[1048];
int sum[1048],left[1048],right[1048];
int ans=1;
bool cmp(edge x,edge y)
{ return x.len
BZOJ1016 最小生成樹計數
題面描述 最小生成樹計數 給定乙個n個點 m條邊的無向圖,求其最小生成樹的個數。相同邊權的邊不會超過10條。思維難度 提高 難度 提高 題解 先給出兩個引理 1.克魯斯卡爾求最小生成數實際上是分成很多個階段的,你可以感受到 很多邊權相同的邊因為排序順序不同,導致它們被訪問的順序不同。但每處理完乙個邊...
bzoj 1016 最小生成樹計數
首先能發現乙個規律,就是重構最小生成樹的時候,一定不可能用一條權值較大的邊和一條權值較小的邊去替換他們中間的兩條邊。簡而言之,就是只能權值相同的邊相互替換。再進一步說,就是每種權值的邊的數目是一定的。題目上說值相同的邊最多10條,那麼我們可以dfs選哪些,然後用並查集來判斷是否成環。這裡要注意,我們...
bzoj 1016 最小生成樹計數
給定乙個簡單無向有權圖,求其最小生成樹的個數。在我們用kruskal計算最小生成樹時,由於相同權值的邊選擇的順序是隨機的,所以我們最小生成樹就也許有很多。對於同一權值的邊,我們不論用什麼順序 掃過 最終的得到的無向森林的連通性一定是一樣的,即對後面的邊是否加入的影響也是一樣的,所以可以根據這一點將最...