python h5网站开发,网站上做视频如何盈利,如何做视频网站,做的好的h游戏下载网站有哪些正题
题目链接:https://www.luogu.com.cn/problem/CF891C 题目大意 nnn个点mmm条边的一张无向联通图#xff0c;每次询问一个边集能否同时出现在同一棵最小生成树上。 1≤n,m,q,wi,∑k≤51051\leq n,m,q,w_i,\sum k\leq 5\times 10^51≤n,m,q,wi,∑k≤5105 解题思路
考虑K…正题
题目链接:https://www.luogu.com.cn/problem/CF891C 题目大意
nnn个点mmm条边的一张无向联通图每次询问一个边集能否同时出现在同一棵最小生成树上。
1≤n,m,q,wi,∑k≤5×1051\leq n,m,q,w_i,\sum k\leq 5\times 10^51≤n,m,q,wi,∑k≤5×105 解题思路
考虑KruskalKruskalKruskal的做法每次找一条最小的边然后判断是否能够加入最小生成树。
考虑到边权相同的边可以任意排序我们把它称之为同一层的边并且无论任意排序最后产生的图的连通情况都不会改变。
我们把一个询问的边按照边分层那么每层的边都合法这个询问就合法。
然后对于一个询问同一层的边直接离线然后把前面的层都加入之后再把所有这些询问边加入判断是否合法即可。因为前面的层不能重新插所以做完要撤销回去。
时间复杂度O(nlogn)O(n\log n)O(nlogn)全部同级的话 code
#includecstdio
#includecstring
#includealgorithm
#includevector
#includestack
using namespace std;
const int N5e510;
struct node{int x,y,w;
}e[N],b[N];
int n,m,Q,k,cnt,fa[N],dep[N],mk[N];
bool ans[N];
vectornode q[N];
vectorint h[N];
stacknode cl;
int find(int x)
{return (fa[x]x)?x:find(fa[x]);}
void unionn(int x,int y){if(dep[x]dep[y])swap(x,y);cl.push((node){x,y,dep[y]});fa[x]y;dep[y]max(dep[y],dep[x]1);return;
}
bool cmp(node x,node y)
{return x.wy.w;}
int main()
{scanf(%d%d,n,m);for(int i1;im;i)scanf(%d%d%d,e[i].x,e[i].y,e[i].w);scanf(%d,Q);for(int i1;iQ;i){int k;scanf(%d,k);for(int j1,x;jk;j)scanf(%d,x),b[j]e[x];sort(b1,b1k,cmp);ans[i]1;for(int j1;jk;j){if(b[j].w!b[j-1].w)cnt,h[b[j].w].push_back(cnt),mk[cnt]i;q[cnt].push_back(b[j]);}}sort(e1,e1m,cmp);for(int i1;in;i)fa[i]i;for(int l1,r1;lm;lr1){while(e[r1].we[l].w)r;int we[l].w;while(!cl.empty())cl.pop();for(int j0;jh[w].size();j){int ph[w][j];for(int i0;iq[p].size();i){int xq[p][i].x,yq[p][i].y;xfind(x);yfind(y);if(xy){ans[mk[p]]0;break;}unionn(x,y);}while(!cl.empty()){node xcl.top();cl.pop();dep[x.y]x.w;fa[x.x]x.x;}}for(int il;ir;i){int xfind(e[i].x),yfind(e[i].y);if(xy)continue;unionn(x,y);}}for(int i1;iQ;i)if(ans[i])puts(YES);else puts(NO);return 0;
}