【CF891C】Envy

题意:给你一个图,边有边权,每次询问给你一堆边,问你是否存在一个原图的最小生成树包含给出的所有边。
n,m,q<=100000

题解:思路很好的题。

首先有一个非常重要的性质,我们每次询问的边中,权值不同的边互不影响。(需要好好想一想,理解一下)

那么满足要求的MST存在当且仅当:对于询问中所有权值相同的边,都存在一个MST同时包含这些边。这又等价于什么?如果我们先把权值小于该权值的所有边先加入到图中求出MST,再把询问的边加入到图中,不能形成环。

于是做法自然就出来了。先离线,将每个询问拆成权值相同的若干个询问,在处理一个询问之前,将权值<询问的边的权值的 所有边都加入到图中求MST。然后处理这个询问,我们将每个连通块看成一个点,然后在连通块之间连边,再用dfs判环即可。最后将这些边删除。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <iostream>
  5. #include <vector>
  6. using namespace std;
  7. const int maxn=500010;
  8. struct node
  9. {
  10. int a,b;
  11. node() {}
  12. node(int x,int y) {a=x,b=y;}
  13. };
  14. int n,m,mx,Q,tot,cnt,flag;
  15. int ans[maxn],vis[maxn],bel[maxn],to[maxn<<1],nxt[maxn<<1],head[maxn],ins[maxn],f[maxn],pc[maxn],pa[maxn],pb[maxn];
  16. vector<node> p[maxn],v[maxn];
  17. vector<int> q[maxn];
  18. vector<node>::iterator vi;
  19. vector<int>::iterator ii;
  20. int find(int x)
  21. {
  22. return (f[x]==x)?x:(f[x]=find(f[x]));
  23. }
  24. inline void add(int a,int b)
  25. {
  26. to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;
  27. to[cnt]=a,nxt[cnt]=head[b],head[b]=cnt++;
  28. }
  29. void dfs(int x,int fa)
  30. {
  31. vis[x]=ins[x]=1;
  32. for(int i=head[x];!flag&&i!=-1;i=nxt[i]) if(i!=(fa^1))
  33. {
  34. if(!vis[to[i]]) dfs(to[i],i);
  35. else if(ins[to[i]]) flag=1;
  36. }
  37. ins[x]=0;
  38. }
  39. inline int rd()
  40. {
  41. int ret=0,f=1; char gc=getchar();
  42. while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
  43. while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
  44. return ret*f;
  45. }
  46. int main()
  47. {
  48. n=rd(),m=rd();
  49. int i,j,a,b,c;
  50. memset(head,-1,sizeof(head));
  51. for(i=1;i<=m;i++) a=pa[i]=rd(),b=pb[i]=rd(),c=pc[i]=rd(),p[c].push_back(node(a,b)),mx=max(mx,c);
  52. Q=rd();
  53. for(i=1;i<=Q;i++)
  54. {
  55. a=rd();
  56. for(j=1;j<=a;j++)
  57. {
  58. b=rd();
  59. if(vis[pc[b]]!=i) vis[pc[b]]=i,bel[pc[b]]=++tot,v[pc[b]].push_back(node(tot,i));
  60. q[bel[pc[b]]].push_back(b);
  61. }
  62. }
  63. for(i=1;i<=n;i++) f[i]=i;
  64. for(i=1;i<=mx;i++)
  65. {
  66. for(vi=v[i].begin();vi!=v[i].end();vi++)
  67. {
  68. j=(*vi).a,cnt=0;
  69. for(ii=q[j].begin();ii!=q[j].end();ii++) add(a=find(pa[*ii]),b=find(pb[*ii])),vis[a]=vis[b]=0;
  70. flag=0;
  71. for(ii=q[j].begin();ii!=q[j].end()&&!flag;ii++)
  72. {
  73. if(!vis[a=find(pa[*ii])]) dfs(a,-1);
  74. if(!vis[b=find(pb[*ii])]) dfs(b,-1);
  75. }
  76. ans[(*vi).b]|=flag;
  77. for(ii=q[j].begin();ii!=q[j].end();ii++) head[find(pa[*ii])]=-1,head[find(pb[*ii])]=-1;
  78. }
  79. for(vi=p[i].begin();vi!=p[i].end();vi++)
  80. {
  81. a=find((*vi).a),b=find((*vi).b);
  82. if(a!=b) f[a]=b;
  83. }
  84. }
  85. for(i=1;i<=Q;i++)
  86. {
  87. if(ans[i]) puts("NO");
  88. else puts("YES");
  89. }
  90. return 0;
  91. }

【CF891C】Envy 离线+最小生成树的更多相关文章

  1. CF891C Envy(离线/在线+可撤销并查集/并查集/LCT)

    前置知识 最小生成树及证明 做法 每个不同权值没影响,仅需判断该次询问每种权值是否在"小于该权值的所有边加完"之后,可以全部加进来 离线:询问的所有边全堆到一起,按权值排序,然后同 ...

  2. CF891C Envy【最小生成树】

    题目链接 我们知道,根据Kruskal的贪心,对于最小生成树,每一种权值的边数是一样的,而且如果将\(\leq x\)的边做最小生成树,合法方案的联通性是一样的.所以我们可以对于所有边分开考虑. 对于 ...

  3. 【CF891C】Envy(最小生成树)

    [CF891C]Envy(最小生成树) 题面 Codeforces 洛谷 题解 考虑\(MST\)的构建过程,对于所有权值相同的边一起考虑. 显然最终他们连出来的结果是固定的. 把连边改为把联通块联通 ...

  4. CF891C Envy 最小生成树/虚树

    正解:最小生成树/虚树 解题报告: 传送门! sd如我就只想到了最暴力的想法,一点儿优化都麻油想到,,,真的菜到爆炸了QAQ 然后就分别港下两个正解QAQ 法一,最小生成树 这个主要是要想到关于最小生 ...

  5. 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树

    [BZOJ4144][AMPPZ2014]Petrol Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油 ...

  6. CF891C Envy

    题面 题解 首先要知道两个性质: 对于任意权值,最小生成树上该权值的边数是相同的. 对于任意一个最小生成树,当加完所有权值小于一个任意值的边之后,当前图的连通性是一样的. 于是我们按照权值分开处理,对 ...

  7. [CF891C] Envy - Kruskal,并查集

    给出一个 n 个点 m条边的无向图,每条边有边权,共 Q次询问,每次给出 \(k\)条边,问这些边能否同时在一棵最小生成树上. Solution 所有最小生成树中某权值的边的数量是一定的 加完小于某权 ...

  8. 题解 [CF891C] Envy

    题面 解析 首先根据Kruskal算法, 我们可以知道, 在加入权值为\(w\)的边时, 权值小于\(w\)的边都已经加进树里了(除了连成环的). 所以,我们可以保存一下每条边的端点在加入生成树之前的 ...

  9. 【题解】CF891CEnvy

    [题解] CF891C Envy 很好玩的一道题.尽管不难,但是调了很久QAQ 考虑克鲁斯卡尔最小生成树的算法,可以发现这些最小树生成的性质: 当生成树所有边的权值都\(\le\)某个$ w$的时刻, ...

随机推荐

  1. 安卓开发笔记——ListView加载性能优化ViewHolder

    在前不久做安卓项目的时候,其中有个功能是爬取某网站上的新闻信息,用ListView展示,虽然做了分页,但还是觉得达不到理想流畅效果. 上网查阅了些资料,发现一些挺不错的总结,这里记录下,便于复习. 当 ...

  2. 和我一起学《HTTP权威指南》——客户端识别与cookie机制

    客户端识别与cookie机制 服务器需要区别是哪个客户端. 个性化接触 HTTP是匿名.无状态的请求/响应协议. Web站点希望: 对客户端的用户有更多的了解 追踪用户浏览页面的行为 因此,产生了几种 ...

  3. “NHibernate.Cfg.Configuration 的类型初始值设定项引发异常。”的解决方法【备忘】

    今天搞到NHibernate时,突然报了一个“NHibernate.Cfg.Configuration 的类型初始值设定项引发异常.”的异常. 详细异常信息“System.IO.FileLoadExc ...

  4. Git------创建本地库时绿色标志不显示

    转载: http://blog.csdn.net/zixiao217/article/details/77018392 解决方法: 按Win+R键打开运行对话框,输入 regedit.exe ,准备修 ...

  5. 反射简介—C#特性和反射

    .NET编译器的任务之一就是为所有定义和引用的类型生成元数据描述.除了程序集中标准的元数据外,.NET平台还支持特定(attribute)把更多的元数据嵌入到程序集中. .NET特性扩展了抽象的Sys ...

  6. sublime自定义代码段

    打开tools>developer>new snippet 默认代码 <snippet> <content><![CDATA[ Hello, ${1:this ...

  7. 03python条件判断与缩进

    if...else...来实现 知识点: 1.多个流程使用elif xxxx : 2.if elif else的语句执行顺序从上而下,只要条件满足,if语句就结束了. 3. 缩进:其他语言用{}包含语 ...

  8. IIS中采用ISAPI-Rewrite防盗链

    本规则支持白名单排除式防盗链,搜索引擎友好(不屏蔽),被盗链后的错误提示转向,支持各种文件类型,经作者亲验真的能用,第一时间在itmop.com原创发表,请继续往下阅读. 近来小站遇到了盗链问题,至使 ...

  9. Linux 常用文件

    /etc/exports /etc/services /etc/sysctl.conf /etc/logrotate.conf /etc/docker/key.json /etc/docker/dae ...

  10. JAVA对URL的解码【转】

    前段时间做URL的中文转换,有些url是utf8的格式,有的是gb2312的格式,很难区分到底是utf8还是gb2312,找了好久,发现网上的一个牛人写的转换代码: package org.apach ...