省选图论专题

news/2024/12/23 20:45:02/文章来源:https://www.cnblogs.com/hzoi-Cu/p/18624994

还没打完数学专题呢就来打这个了。(其实是不会多项式)

难度大概升序。

Giving Awards

注意到一个关键信息:每对人只会被提到一次。所以一定有解。

考虑卡bug,假如\(a\)\(b\)钱,那么就先让\(b\)取钱再让\(a\)取钱,建边dfs即可,注意图不连通。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
const int N = 3e4 + 10;
#define eb emplace_back
vector<int> e[N],ans;
bitset<N> vis;
int n,m,d[N];
void dfs(int x,int fa){vis[x] = true;for(auto y:e[x]){if(vis[y]) continue;dfs(y,x);}ans.emplace_back(x);
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cin>>n>>m;rep(i,1,m,1){int x,y;cin>>x>>y;e[x].eb(y);}rep(i,1,n,1) if(!vis[i]) dfs(i,0);for(auto i:ans) cout<<i<<' ';
}

[BJWC2010] 严格次小生成树

一个结论:次小生成树与最小生成树只会有一条边不同。

先将最小生成树求出来,然后考虑所有的非树边,发现这条边\((u,v,w)\)替换的必定是\(u\rightarrow LCA(u,v),v\rightarrow LCA(u,v)\)上的一条边\((u^\prime,v^\prime,w^\prime),w^\prime < w\)

那么现在就是求\(u\rightarrow v\)的简单路径上所有的边中,\(w\)的前驱。

不会倍增,只会树剖+线段树,考虑将所有树边排序,每次查询非树边时,将所有权值小于它的假如,然后求链上最大值即可,但是边权不好做,考虑边权转点权即可,时间复杂度\(O(m\log^2 n)\),但是由于树剖常数小,跑的和倍增差不多,而且空间比倍增优秀。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
#define eb emplace_back
const int N = 1e5 + 10,M = 3e5 + 10;
vector<pair<int,int> > e[N];
int n,m;struct node{int x,y,z;}edge[M];
bitset<M> unused;
int dist[N],top[N],siz[N],son[N],dfn[N],rdfn[N],tim,dep[N],fa[N];
struct DSU{vector<int> fa;void init(int n){fa.resize(n+1);rep(i,1,n,1) fa[i] = i;}int get_fa(int x){while(x ^ fa[x]) x = fa[x] = fa[fa[x]];return x;}bool Merge(int x,int y){x = get_fa(x),y = get_fa(y);if(x == y) return false;return fa[x] = y,true;}
}D;
struct Segment_Tree{struct segment_tree{int l,r,val;#define l(x) tree[x].l#define r(x) tree[x].r#define val(x) tree[x].val}tree[N<<2];void B(int k = 1,int l = 1,int r = n){l(k) = l,r(k) = r;if(l == r) return;int mid = (l + r) >> 1;B(k<<1,l,mid);B(k<<1|1,mid+1,r);}void upd(int k,int pos,int val){if(l(k) == r(k)) return val(k) = val,void();int mid = (l(k) + r(k)) >> 1;pos <= mid?upd(k<<1,pos,val):upd(k<<1|1,pos,val);val(k) = max(val(k<<1),val(k<<1|1));}int qry(int k,int l,int r){if(l <= l(k) && r(k) <= r) return val(k);int mid = (l(k) + r(k)) >> 1,res = 0;if(l <= mid) res = max(res,qry(k<<1,l,r));if(r > mid) res = max(res,qry(k<<1|1,l,r));return res;}
}T;
void dfs1(int x){siz[x] = 1,dep[x] = dep[fa[x]] + 1;for(auto [y,w]:e[x]){if(y == fa[x]) continue;fa[y] = x;dfs1(y);dist[y] = w;siz[x] += siz[y];if(siz[son[x]] < siz[y]) son[x] = y;}
}
void dfs2(int x,int t){top[x] = t;rdfn[dfn[x] = ++tim] = x;if(son[x]) dfs2(son[x],t);else return;for(auto [y,w]:e[x]){if(y == fa[x] || y == son[x]) continue;dfs2(y,y);}
}
int query(int x,int y){int fx = top[x],fy = top[y];int res = 0;while(fx ^ fy){if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);res = max(res,T.qry(1,dfn[fx],dfn[x]));x = fa[fx];fx = top[x];}if(dep[x] > dep[y]) swap(x,y);if(x == y) return res;res = max(res,T.qry(1,dfn[x]+1,dfn[y]));return res;
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cin>>n>>m;rep(i,1,m,1) cin>>edge[i].x>>edge[i].y>>edge[i].z;D.init(n);sort(edge+1,edge+1+m,[](node x,node y){return x.z < y.z;});ll total = 0;rep(i,1,m,1){auto [x,y,w] = edge[i];auto flag = D.Merge(x,y);if(!flag){unused[i] = true;continue;}e[x].eb(y,w);e[y].eb(x,w);total += w;}dfs1(1);dfs2(1,1);T.B();int ans = 1e9;int now = 1;rep(i,1,m,1){auto [x,y,w] = edge[i];while(now <= m && edge[now].z < w){if(unused[now]){now++;continue;}auto [x,y,w] = edge[now];if(fa[x] == y) T.upd(1,dfn[x],edge[now].z);if(fa[y] == x) T.upd(1,dfn[y],edge[now].z);now++;}if(!unused[i]) continue;if(x == y) continue;int res = w-query(x,y);ans = min(ans,res);}cout<<total + ans<<'\n';
}

跳楼机

同余最短路板子,当个学习笔记写。

当出现形如

  1. 给定 \(n\) 个整数,求这 \(n\) 个整数能拼凑出多少的其他整数 (\(n\) 个整数可以重复取)。
  2. 给定 \(n\) 个整数,求这 \(n\) 个整数不能拼凑出的最小(最大)的整数。
  3. 至少要拼几次才能拼出模 \(K\)\(p\) 的数

等问题时可以使用同余最短路的方法。

既然带了最短路,那么就类比最短路。同余最短路中的转移通常是\(f(i+y)=f(i)+y\),类比\(dist_v=dist_u+e(u,v)\)

考虑这道题,设\(d_i\)表示通过\(2,3\)操作,满足\(p\bmod x=i\)的最小的\(p\),那么就有\(f((i+y)\bmod x)=f(i)+y,f((i+z)\bmod x)=f(i)+z\)。实质上就是最短路中的加边操作,接下来只需要求出\(d_0,d_1,\ldots,d_{x-1}\)即可,答案为\(\sum\limits_{i=0}^{x-1}[h\ge d_i](\frac{h-d_i}{x}+1)\)。但是由于本题\(h\le 2^{63}-1\),求解时\(d\)的初值至少应为\(2^63>LLONG\_MAX\),所以可以将\(h\leftarrow h-1\),将初始楼层设为\(0\)即可。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
#define int ull
const int N = 1e5 + 10;
int h,x,y,z,dist[N];
vector<pair<int,int> > e[N];
bitset<N> vis;
void dijkstra(){memset(dist,0x3f,sizeof dist);priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;q.emplace(0,0);dist[0] = 0;while(q.size()){int x = q.top().second;q.pop();if(vis[x]) continue;vis[x] = true;for(auto [y,w]:e[x]){if(dist[y] > dist[x] + w){dist[y] = dist[x] + w;q.emplace(dist[y],y);}}}
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cin>>h>>x>>y>>z;h--;rep(i,0,x-1,1){e[i].emplace_back((i+y)%x,y);e[i].emplace_back((i+z)%x,z);}dijkstra();int ans = 0;rep(i,0,x-1,1) if(h >= dist[i]) ans += (h-dist[i])/x+1;cout<<ans<<'\n';
}

[国家集训队] 墨墨的等式

显然答案具有可差分性,考虑求出\([0,l),[0,r]\)中的可以凑出的值作差即可,处理方法同上。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
const int N = 5e5 + 10;
int n,x;bitset<N> vis;
vector<pair<int,int> > e[N];
ll l,r,dist[N];
vector<int> num;
void dijkstra(int s){memset(dist,0x3f,sizeof dist);priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;q.emplace(0,0);dist[0] = 0;while(q.size()){int x = q.top().second;q.pop();if(vis[x]) continue;vis[x] = true;for(auto [y,w]:e[x]){if(dist[y] > dist[x] + w){dist[y] = dist[x] + w;q.emplace(dist[y],y);}}}
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cin>>n>>l>>r>>x;l--;rep(i,2,n,1){int x;cin>>x;num.emplace_back(x);}rep(i,0,x-1,1) for(auto j:num) e[i].emplace_back((i+j)%x,j);dijkstra(0);ll ans = 0;rep(i,0,x-1,1) if(l >= dist[i]) ans -= (l-dist[i])/x+1;rep(i,0,x-1,1) if(r >= dist[i]) ans += (r-dist[i])/x+1;cout<<ans<<'\n';
}

Fairy

【模板】线段树分治

线段树分治太naive了,考虑换个优秀的做法。

显然答案为奇环交,考虑如何求这个。考虑跑一遍dfs,求出一颗生成树。

对于一条非树边,显然会形成一个环,称这个环上的树边被其覆盖。

如果一条非树边和树边形成一个有且仅有这一条非树边的奇环,那么称这条非树边为坏边。

显然答案边被所有坏边覆盖,且不被好边覆盖。

然后直接树上差分就可以了,时间复杂度\(O(n)\)

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
const int N = 1e4 + 10;
#define eb emplace_back
vector<int> e[N],id[N],ans;
bitset<N> vis;
bool dis[N],ok[N];
int s[N],ct,eid,n,m;
void dfs(int x){vis[x] = true;rep(i,0,(int)e[x].size()-1,1){int y = e[x][i];if(!vis[y]){dis[y] = dis[x]^1;ok[id[x][i]] = 1;dfs(y);}else if(!ok[id[x][i]]){ok[id[x][i]] = 1;if(dis[y] == dis[x]){ct++;s[x]++;s[y]--;eid = id[x][i];}else s[x]--,s[y]++;}}
}
void dfs1(int x){vis[x] = true;rep(i,0,(int)e[x].size() - 1,1){int y = e[x][i];if(!vis[y]){dfs1(y);if(s[y] == ct) ans.emplace_back(id[x][i]);s[x] += s[y];}}
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cin>>n>>m;rep(i,1,m,1){int u,v;cin>>u>>v;e[u].eb(v);e[v].eb(u);id[u].eb(i);id[v].eb(i);}rep(i,1,n,1) if(!vis[i]) dfs(i);if(!ct){cout<<m<<'\n';rep(i,1,m,1) cout<<i<<' ';return 0;}vis.reset();rep(i,1,n,1) if(!vis[i]) dfs1(i);if(ct == 1) ans.emplace_back(eid);cout<<ans.size()<<'\n';sort(ans.begin(),ans.end());for(auto i:ans) cout<<i<<' ';
}

[中山市选] 杀人游戏

一眼下去答案为\(\frac{n-缩点后入度为0的点的个数}{n}\)。然后喜提30pts。

考虑哪里有问题呢?贪心的想,我们可以将强连通分量中个数为\(1\)且所连的点的入度都\(>1\)的点放在最后一个询问,如果其它点都确定了,那么这个点显然不用问,答案为\(\frac{n-缩点后入度为0的点的个数}{n}\)

本题卡精度,输出答案时应加上eps。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
const int N = 1e5 + 10;
#define eb emplace_back
int n,m;vector<int> e[N];
int dfn[N],low[N],tim,sta[N],top;
int tot = 0,g[N],u[N],v[N],d[N],siz[N],ct[N],out[N];
bitset<N> insta;set<int> pd[N];
void Tarjan(int x){dfn[x] = low[x] = ++tim;sta[++top] = x;insta[x] = true;for(auto y:e[x]){if(!dfn[y]) Tarjan(y),low[x] = min(low[x],low[y]);else if(insta[y]) low[x] = min(low[x],dfn[y]);}if(dfn[x] == low[x]){int y;tot++;do{y = sta[top--];g[y] = tot;insta[y] = false;siz[tot]++;}while(y != x);}
}
vector<pair<int,int> > E;
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cin>>n>>m;rep(i,1,m,1){int u,v;cin>>u>>v;if(pd[u].count(v)) continue;pd[u].insert(v);e[u].eb(v);E.eb(u,v);}rep(i,1,n,1) pd[i].clear();rep(i,1,n,1) if(!dfn[i]) Tarjan(i);for(auto [x,y]:E){if(g[x] == g[y]) continue;if(pd[g[x]].count(g[y])) continue;pd[g[x]].insert(g[y]);out[g[x]]++;d[g[y]]++;}ldb ans = 0;for(auto [x,y]:E){if(g[x] == g[y]) continue;if(d[g[y]] >= 2) ct[g[x]]++;}rep(i,1,tot,1){if(!d[i] && ct[i] == out[i] && siz[i] == 1){ans -= 1;break;}}rep(i,1,tot,1){if(!d[i])ans += 1;}cout<<fixed<<setprecision(6);cout<<1.0*(n-ans)/n+1e-9<<'\n';
}

[NOI2018] 归程

模板:kruskal重构树。

就是用kruskal时,将两个点中间创建一个虚点,点权记为边权。

有如下性质:

  1. 两个点之间的所有简单路径上最大边权的最小值 = 最小生成树上两个点之间的简单路径上的最大值 = Kruskal 重构树上两点之间的 LCA 的权值。
  2. 如果以最小生成树的方式建树,那么建出的树是大根堆的形式。

本题则求最大生成树,就利用小根堆的性质,建出kruskal重构树后,每个点维护子树内\(1\)到子树内的点的最小值。

由于不会倍增,考虑树剖暴力跳,如果发现链顶无法达到,那么就在这条重链上二分即可。注意树剖清空,不然会导致奇怪错误。

时间复杂度\(O(m\log m + q\log n)\)

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
#define int ll
#define eb emplace_back
const int N = 4e5 + 10;
vector<pair<int,int> > e[N],t[N];
struct Edge{int x,y,l,a;}edge[N];
int n,m,vtot,fa[N],siz[N],son[N],top[N],dfn[N],rdfn[N],tim,dep[N],dis[N],lastans;
int v,p,q,k,s;
ll dist[N];
bitset<N> vis;
void dijkstra(int s = 1){memset(dist,0x3f,sizeof dist);vis.reset();priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;dist[s] = 0;q.emplace(0,s);while(q.size()){int x = q.top().second;q.pop();if(vis[x]) continue;vis[x] = true;for(auto [y,w]:e[x]){if(dist[y] > dist[x] + w){dist[y] = dist[x] + w;q.emplace(dist[y],y);}}}
}
struct DSU{vector<int> fa;void init(int n){fa.resize(n+1); rep(i,1,n,1) fa[i] = i;}int get_fa(int x){while(x ^ fa[x]) x = fa[x] = fa[fa[x]];return x;}bool Merge(int x,int y){x = get_fa(x),y = get_fa(y);if(x == y) return false;if(x > y) swap(x,y);return fa[x] = y,true;}
}D;
void dfs1(int x){dep[x] = dep[fa[x]] + 1;siz[x] = 1;for(auto [y,w]:t[x]){if(y == fa[x]) continue;dis[y] = w;fa[y] = x;dfs1(y);siz[x] += siz[y];dist[x] = min(dist[x],dist[y]);if(siz[son[x]] < siz[y]) son[x] = y;}
}
void dfs2(int x,int tp){top[x] = tp;rdfn[dfn[x] = ++tim] = x;if(son[x]) dfs2(son[x],tp);else return;for(auto [y,w]:t[x]){if(y == fa[x] || y == son[x]) continue;dfs2(y,y);}
}
void init(){rep(i,1,n*2+10,1) e[i].clear(),t[i].clear();memset(fa,0,sizeof fa);memset(siz,0,sizeof siz);memset(dfn,0,sizeof dfn);memset(rdfn,0,sizeof rdfn);memset(dep,0,sizeof dep);memset(top,0,sizeof top);memset(son,0,sizeof son);sort(edge+1,edge+1+m,[](Edge x,Edge y){return x.a > y.a;});D.init(n*2+10);rep(i,1,m,1){auto [x,y,l,a] = edge[i];e[x].eb(y,l);e[y].eb(x,l);if(D.get_fa(x) == D.get_fa(y)) continue;vtot++;t[vtot].eb(D.get_fa(x),a);t[vtot].eb(D.get_fa(y),a);t[D.get_fa(x)].eb(vtot,a);t[D.get_fa(y)].eb(vtot,a);D.fa[D.get_fa(x)] = vtot;D.fa[D.get_fa(y)] = vtot;}dijkstra();dfs1(vtot);tim = 0;dfs2(vtot,vtot);
}
int get(int v,int p){int x = v,fx = top[x];while(x && dis[fx] > p) x = fa[fx],fx = top[x];int l = dfn[fx],r = dfn[x],res = 0;while(l <= r){int mid = (l + r) >> 1;if(dis[rdfn[mid]] <= p) res = rdfn[mid],l = mid + 1;else r = mid - 1;}if(!res || res == 1) return 0;return dist[res];
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);
int T;cin>>T;
rep(Test,1,T,1){cin>>n>>m;vtot = n;lastans = 0;rep(i,1,m,1)cin>>edge[i].x>>edge[i].y>>edge[i].l>>edge[i].a;init();cin>>q>>k>>s;rep(test,1,q,1){cin>>v>>p;v = (v+k*lastans - 1)%n+1;p = (p+k*lastans)%(s+1);cout<<(lastans = get(v,p))<<'\n';}
}
}

Xor-MST

考虑Boruvka算法,那么就只需要考虑如果对于每个点,快速求出不在其连通块中最小连边。

求异或最小值,考虑01-trie,建一个全局trie,然后对于每个连通块,维护每个连通块的trie,然后记录每个节点的size,对于每个点,在全局trie中查找,如果减去其所在连通块中的size仍有,正常跑就行,合并两个连通块的时候,启发式合并它们的trie即可。

时间复杂度\(O(n\log n\log V)\),空间复杂度\(O(n\log V)\)

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace __gnu_pbds;
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCALauto I = freopen("in.in","r",stdin),O = freopen("out.out","w",stdout);
#elseauto I = stdin,O = stdout;
#endif
using ll = long long;using ull = unsigned long long;
using db = long double;using ldb = long double;
const int N = 2e5 + 10;
const ll inf = 1e15;
int n,a[N],rt[N],to[N];
ll mn[N];
struct Trie{int tree[N*60][2],siz[N*60],tot,ed[N*60];void insert(int &x,int dep,int w,int id){if(!x) x = ++tot;if(dep < 0) return ed[x] = id,siz[x] = 1,void();int c = w>>dep&1;insert(tree[x][c],dep-1,w,id);siz[x]++;}int Merge(int x,int y){if(!x || !y) return x|y;tree[x][0] = Merge(tree[x][0],tree[y][0]);tree[x][1] = Merge(tree[x][1],tree[y][1]);siz[x] = siz[tree[x][0]] + siz[tree[x][1]];ed[x] = ed[y];return x;}pair<int,int> get(int x,int pre,int w){int ans = 0;drep(i,30,0,1){int c = w>>i&1;if(tree[x][c] && siz[tree[x][c]] - siz[tree[pre][c]] > 0) x = tree[x][c],pre = tree[pre][c];else ans |= 1<<i,x = tree[x][c^1],pre = tree[pre][c^1];}return make_pair(ans,ed[x]);}
}T;
struct DSU{vector<int> fa,siz;int tot;void init(int n){tot = n;fa.resize(n+1),siz.resize(n+1,1);rep(i,1,n,1) fa[i] = i;}int get_fa(int x){while(x ^ fa[x]) x = fa[x] = fa[fa[x]];return x;}pair<int,int> Merge(int x,int y){x = get_fa(x),y = get_fa(y);if(x == y) return make_pair(0,0);tot--;if(siz[x] > siz[y]) swap(x,y);fa[x] = y;siz[y] += siz[x];return make_pair(x,y);}
}D;
signed main(){cin.tie(nullptr)->sync_with_stdio(false);vector<int> num;cin>>n;rep(i,1,n,1) cin>>a[i],num.emplace_back(a[i]);sort(a+1,a+1+n);n = unique(a+1,a+1+n) - a - 1;rep(i,1,n,1) T.insert(rt[0],30,a[i],i),T.insert(rt[i],30,a[i],i);D.init(n);bitset<N> vis;ll ans = 0;int tot = 0;while(D.tot != 1){tot++;rep(i,1,n,1) mn[i] = inf;rep(i,1,n,1){auto res = T.get(rt[0],rt[D.get_fa(i)],a[i]);if(res.first < mn[D.get_fa(i)]) mn[D.get_fa(i)] = res.first,to[D.get_fa(i)] = D.get_fa(res.second);}bool flag = true;rep(i,1,n,1){if(mn[i] == inf) continue;flag &= false;auto res = D.Merge(i,to[i]);if(res.first) T.Merge(rt[res.second],rt[res.first]),ans += mn[i];}}cout<<ans<<'\n';
}

\(to\;be\;continued\)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/857654.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php网络编程swoole websocket

服务端:<?php use Swoole\WebSocket\Server;// 创建 HTTP 服务器 $server = new Server(127.0.0.1, 8888, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);$server->on(start, function ($server) {//print_r($server);echo "Swoole websocket server is started at ws://127.…

php网络编程swoole udp

服务端:<?php $server = new Swoole\Server(127.0.0.1, 9504, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);$server->on(start, function ($server) {echo "UDP Server is started at udp://127.0.0.1:9504\n"; });$server->on(packet, function ($server, $data, …

第36次ccf-csp题解(思维)

比赛链接 https://sim.csp.thusaac.com/contest/36/home比赛感受这会刚打完上海icpc,比起区域赛的题,这个简单太多了。 感受还不错,写的很顺手。除了第3题,其他3题都是一发过。 刷题得长期刷。 A题 移动题意:f : y+1 ;  b : y-1 ;   l : x-1 ;  r : x+1 一个简单的模…

php网络编程swoole http

服务端:<?php use Swoole\Http\Server; use Swoole\Http\Request; use Swoole\Http\Response;// 创建 HTTP 服务器 $server = new Server(127.0.0.1, 9501);$server->on(start, function ($server) {//print_r($server);echo "Swoole http server is started at h…

JVM简介—2.垃圾回收器和内存分配策略

大纲 1.垃圾回收概述 2.如何判断对象存活 3.各种引用介绍 4.垃圾收集的算法 5.垃圾收集器的设计 6.垃圾回收器列表 7.各种垃圾回收器详情 8.Stop The World现象 9.内存分配与回收策略 10.新生代不同配置演示 11.内存泄漏和内存溢出 12.JDK为提供的工具1.垃圾回收概述 2.如何判…

OpenAI 推出嵌入式硬件 SDK,支持 ESP32 语音开发;INFP:音频驱动的双人对话头像生成,自动区分说话者和倾听者

开发者朋友们大家好:这里是 「RTE 开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编辑…

8086汇编(16位汇编)学习笔记02.分段,机器码和寻址

原文链接:https://bpsend.net/thread-112-1-2.html 分段问题1 8086是16位cpu,最多可以访问(寻址)多大内存?运算器一次最多处理16位的数据。地址寄存器的最大宽度为16位。访问的最大内存为:216 = 64K 即 0000 - FFFF。问题2 8086允许最大内存1M,如何实现访问(寻址)到所…

AI对话机器人续:将AI Bot接入企业微信

之前尝试将Coze AI Bot接入到了微信,有朋友问如何接入企业微信,今天有空尝试了下,和你分享一下过程。整体流程和步骤还是基于chatgpt-on-wechat这个开源框架来的,唯一的差别就在于部署chatgpt-on-wechat的时候,需要填写一些企业微信相关的参数和secret。大家好,我是Ediso…

python网络编程之udp

服务端:import socketsk = socket.socket(type=socket.SOCK_DGRAM) # 表示一个udp协议 sk.bind((127.0.0.1, 9504))# 服务端不能先发送消息,因为服务端不知道客户端的ip while True:msg, addr = sk.recvfrom(1024)print(f"接收到客户端数据:{msg.decode(utf-8)}"…

Qt编程快速入门(1)Qt结构简介

Qt构成Qt(/ˈkjuːt/,发音同“cute”)是一个跨平台的C++应用程序开发框架。广泛用于开发GUI程序,这种情况下又被称为部件工具箱。也可用于开发非GUI程序,例如控制台工具和服务器。-摘自维基百科Qt可以在多个平台编译运行,包括Windows、Linux、Mac OS,其运行时的表现取决…

python网络编程之websocket

服务端:import asyncio import websockets# 保存已连接的客户端列表 connected_clients = set()async def handle_websocket(websocket):# 将新的客户端添加到已连接客户端列表remote_address = websocket.remote_addressconnected_clients.add(websocket)print(f"新的客…

.NET 阻止系统睡眠/息屏

本文介绍Windows系统设备下如何阻止系统睡眠/息屏,以及想看当前阻止睡眠/息屏的应用信息 powercfg /requests查看活动列表 在播放音乐时,我们会发现设置了系统电源管理-自动睡眠,计划不会生效,这个音频播放操作阻止了系统自动睡眠。但不会阻止息屏,所以Windows下一般屏幕关…