codeforces 891C
来源:互联网 发布:贷款软件 编辑:程序博客网 时间:2024/05/22 17:57
给出一个无向图,每次询问图中的一个边集,是否存在包含这个边集的MST
考虑怎么判断是否存在包含某一条边的MST
若他不在原图的MST上,显然只能尝试用它替换一条权值相等的,MST上的边
设他的权值为c,可以先对权< c的边先做kruskal建出生成树,用这些边将原图缩点
然后若这条边在这个缩完点的图上不是自环,就合法
对于每个询问的边集,不同的边权显然互相独立
这个边集合法的充要条件是每条边合法且相同边权的边在它的那个图上不成环
将这些询问离线掉,按边权从小到大建出图,每一步后缩点,然后对于每个询问若他有当前权的边就判这些边是否成环
判环好像有一些高级的随机分配值用异或判的姿势但我不会
我们可以直接暴力的用并查集判环
但每个询问判完后要撤销操作所以写按秩合并的并查集,带个log
nlogn
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void read(int &x){ char c; while(!((c=getchar())>='0'&&c<='9')); x=c-'0'; while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';}const int maxn = 510000;const int maxm = 510000;const int maxq = 510000;int n,m,q;struct edge{int i,x,y,c;}e[maxm]; int To[maxm];inline bool cmp(const edge x,const edge y){return x.c<y.c;}struct node{int i,j,x;};inline bool operator <(const node x,const node y){return x.x>y.x;}priority_queue<node>Q;vector<int>V[maxq];int ans[maxq];int fa[maxn],siz[maxn];int t[maxn][2],tp;int findfa(const int x){return fa[x]==x?x:findfa(fa[x]);}bool merge(int ei){ int x=e[ei].x,y=e[ei].y; int f1=findfa(x),f2=findfa(y); if(f1==f2) return false; if(siz[f1]<siz[f2]) swap(f1,f2); fa[f2]=f1,siz[f1]+=siz[f2]; t[++tp][0]=f1,t[tp][1]=f2; return true;}void gback(){ while(tp) { int x=t[tp][0],y=t[tp--][1]; fa[y]=y; siz[x]-=siz[y]; }}int main(){ read(n); read(m); for(int i=1;i<=m;i++) read(e[i].x),read(e[i].y),read(e[i].c),e[i].i=i; sort(e+1,e+m+1,cmp); for(int i=1;i<=m;i++) To[e[i].i]=i; read(q); for(int i=1;i<=q;i++) { ans[i]=0; int kk; read(kk); while(kk--) { int cc; read(cc); cc=To[cc]; V[i].push_back(cc); }kk=V[i].size(); sort(V[i].begin(),V[i].end()); Q.push((node){i,0,V[i][0]}); } for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1; for(int i=1;i<=m;) { int j=i+1;for(;j<=m&&e[j].c==e[i].c;j++);j--; while(!Q.empty()) { node now=Q.top(); if(now.x>j) break; Q.pop(); for(;now.j<V[now.i].size()&&V[now.i][now.j]<=j;now.j++) if(!merge(V[now.i][now.j])) break; gback(); if(now.j==V[now.i].size()) { ans[now.i]=1; continue; } now.x=V[now.i][now.j]; if(now.x>j) Q.push(now); } for(;i<=j;i++) merge(i); tp=0; } for(int i=1;i<=q;i++) puts(ans[i]==1?"YES":"NO"); return 0;}
阅读全文
0 0
- [Codeforces 891C] Envy
- codeforces 891C
- CF——Codeforces 891 C Envy
- Codeforces-340-C(c++)
- Codeforces-507-C(c++)
- CodeForces 731C C
- CodeForces-612C C
- CODEFORCES 265C CODEFORCES, 265C
- codeforces #78 div2 C
- Codeforces 117C Cycle
- CodeForces 209C
- CodeForces 156C Cipher
- codeforces 148 div2 C
- codeforces 242C
- Codeforces-234C Weather
- codeforces 106C Buns
- codeforces 158C
- Codeforces 243C
- IOS,将阿拉伯数字转换为中文数字
- MySQL之数据存储索引篇(二)
- 使用MFC快速创建一个窗口程序
- 2.2版本回退,复位
- Python入门教程(一)manage.py和django-admin.py的区别
- codeforces 891C
- 搭建一个简易的时间服务器笔记----C++学习之路
- 有关电脑的基本技能
- 使用Construct 2制作HTML5游戏(进阶篇)
- HDU 1905 + POJ 1730 【快速幂】
- Linux系统的软件组成
- 两杯水交换
- Android开发小结——UI开发
- Android UI基础之ListView 和适配器Adapter