給定乙個 n 個點 m 條邊的連通無向圖,其中點從 1 到 n 標號,而每條邊有乙個危險值。
對於任意一條路徑,定義路徑上危險值的最大值為這條路徑的危險值。
對於任意不同的兩點 u 和 v,定義 d(u, v) 為所有從 u 到 v 的路徑的危險值最小值。 fu
=∑u!
=vd(
u,v)
求⊕i=1n(
i⋅f(
i))
最小生成樹+啟發合併
對集合維護集合裡的值和真值的差。
#include
using namespace std;
#define for(i,n) for(int i=1;i<=n;i++)
#define fork(i,k,n) for(int i=k;i<=n;i++)
#define forkd(i,k,n) for(int i=n;i>=k;i--)
#define rep(i,n) for(int i=0;i#define ford(i,n) for(int i=n;i;i--)
#define repd(i,n) for(int i=n;i>=0;i--)
#define forp(x) for(int p=pre[x];p;p=next[p])
#define forpiter(x) for(int &p=iter[x];p;p=next[p])
#define lson (o<<1)
#define rson ((o<<1)+1)
#define mem(a) memset(a,0,sizeof(a));
#define memi(a) memset(a,0x3f,sizeof(a));
#define memi(a) memset(a,128,sizeof(a));
#define memx(a,b) memset(a,b,sizeof(a));
#define inf (0x3f3f3f3f)
#define f (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector
#define pi pair
#define si(a) ((a).size())
#define pr(kcase,ans) printf("case #%d: %lld\n",kcase,ans);
#define pri(a,n) for(i,n-1) cout<#define pri2d(a,n,m) for(i,n)
ll add(ll a,ll b)
ll sub(ll a,ll b)
void upd(ll &a,ll b)
inline int read()
while(isdigit(ch))
return x*f;
} int t,n,m;
#define maxn (112345)
class bingchaji
}int getfather(int x)
void unite(int x,int y)
}bool same(int x,int y)
}s;#define maxm (312345)
struct edge
sort(e+1,e+1+m);
s.mem(n);
for(i,m)
s.father[t1]=t2; }}
ull ret=0;
int u=s.getfather(1);
ull t=s.sum[u];
for(auto p:s.g[u])
printf("case #%d: ",kcase);
cout0;}
啟發式合併
啟發式合併 暴力合併 將兩個資料結構合併,只需要將小的資料結構中的元素乙個乙個的插入大的資料結構o n o n o n 如果題目只有插入操作沒有 總o n logn o nlogn o nlog n 因為每次合併,所有資料結構總大小為n,設兩個資料結構大小為a,b a b a,b a b a,b a...
啟發式合併
includeconst int n 5e5 5 int f n d n r n p n int find int i int unionn int i,int j int main 並查集 按秩啟發式合併 bzoj4668 冷戰 題目大意 給出n個軍工廠和m 個操作,操作分為兩類 0 u v,這次...
啟發式合併
啟發式合併本質上是一種優化的暴力,可用於擁有穩定結構的資料結構。考慮夢幻布丁 hnoi2009 顯然的暴力思路是用鍊錶維護每種顏色的位置,然後每次修改的時候暴力合併兩條鏈。不難證明,這樣的最壞時間複雜度將達到 o n 2 不能接受。可以觀察到,合併的時間複雜度只與被合併的鏈長度有關,所以可以想到優化...