【CF891C】Envy 离线+最小生成树
【CF891C】Envy
题意:给你一个图,边有边权,每次询问给你一堆边,问你是否存在一个原图的最小生成树包含给出的所有边。
n,m,q<=100000
题解:思路很好的题。
首先有一个非常重要的性质,我们每次询问的边中,权值不同的边互不影响。(需要好好想一想,理解一下)
那么满足要求的MST存在当且仅当:对于询问中所有权值相同的边,都存在一个MST同时包含这些边。这又等价于什么?如果我们先把权值小于该权值的所有边先加入到图中求出MST,再把询问的边加入到图中,不能形成环。
于是做法自然就出来了。先离线,将每个询问拆成权值相同的若干个询问,在处理一个询问之前,将权值<询问的边的权值的 所有边都加入到图中求MST。然后处理这个询问,我们将每个连通块看成一个点,然后在连通块之间连边,再用dfs判环即可。最后将这些边删除。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int maxn=500010;
struct node
{
int a,b;
node() {}
node(int x,int y) {a=x,b=y;}
};
int n,m,mx,Q,tot,cnt,flag;
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];
vector<node> p[maxn],v[maxn];
vector<int> q[maxn];
vector<node>::iterator vi;
vector<int>::iterator ii;
int find(int x)
{
return (f[x]==x)?x:(f[x]=find(f[x]));
}
inline void add(int a,int b)
{
to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,nxt[cnt]=head[b],head[b]=cnt++;
}
void dfs(int x,int fa)
{
vis[x]=ins[x]=1;
for(int i=head[x];!flag&&i!=-1;i=nxt[i]) if(i!=(fa^1))
{
if(!vis[to[i]]) dfs(to[i],i);
else if(ins[to[i]]) flag=1;
}
ins[x]=0;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,j,a,b,c;
memset(head,-1,sizeof(head));
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);
Q=rd();
for(i=1;i<=Q;i++)
{
a=rd();
for(j=1;j<=a;j++)
{
b=rd();
if(vis[pc[b]]!=i) vis[pc[b]]=i,bel[pc[b]]=++tot,v[pc[b]].push_back(node(tot,i));
q[bel[pc[b]]].push_back(b);
}
}
for(i=1;i<=n;i++) f[i]=i;
for(i=1;i<=mx;i++)
{
for(vi=v[i].begin();vi!=v[i].end();vi++)
{
j=(*vi).a,cnt=0;
for(ii=q[j].begin();ii!=q[j].end();ii++) add(a=find(pa[*ii]),b=find(pb[*ii])),vis[a]=vis[b]=0;
flag=0;
for(ii=q[j].begin();ii!=q[j].end()&&!flag;ii++)
{
if(!vis[a=find(pa[*ii])]) dfs(a,-1);
if(!vis[b=find(pb[*ii])]) dfs(b,-1);
}
ans[(*vi).b]|=flag;
for(ii=q[j].begin();ii!=q[j].end();ii++) head[find(pa[*ii])]=-1,head[find(pb[*ii])]=-1;
}
for(vi=p[i].begin();vi!=p[i].end();vi++)
{
a=find((*vi).a),b=find((*vi).b);
if(a!=b) f[a]=b;
}
}
for(i=1;i<=Q;i++)
{
if(ans[i]) puts("NO");
else puts("YES");
}
return 0;
}
【CF891C】Envy 离线+最小生成树的更多相关文章
- CF891C Envy(离线/在线+可撤销并查集/并查集/LCT)
前置知识 最小生成树及证明 做法 每个不同权值没影响,仅需判断该次询问每种权值是否在"小于该权值的所有边加完"之后,可以全部加进来 离线:询问的所有边全堆到一起,按权值排序,然后同 ...
- CF891C Envy【最小生成树】
题目链接 我们知道,根据Kruskal的贪心,对于最小生成树,每一种权值的边数是一样的,而且如果将\(\leq x\)的边做最小生成树,合法方案的联通性是一样的.所以我们可以对于所有边分开考虑. 对于 ...
- 【CF891C】Envy(最小生成树)
[CF891C]Envy(最小生成树) 题面 Codeforces 洛谷 题解 考虑\(MST\)的构建过程,对于所有权值相同的边一起考虑. 显然最终他们连出来的结果是固定的. 把连边改为把联通块联通 ...
- CF891C Envy 最小生成树/虚树
正解:最小生成树/虚树 解题报告: 传送门! sd如我就只想到了最暴力的想法,一点儿优化都麻油想到,,,真的菜到爆炸了QAQ 然后就分别港下两个正解QAQ 法一,最小生成树 这个主要是要想到关于最小生 ...
- 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树
[BZOJ4144][AMPPZ2014]Petrol Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油 ...
- CF891C Envy
题面 题解 首先要知道两个性质: 对于任意权值,最小生成树上该权值的边数是相同的. 对于任意一个最小生成树,当加完所有权值小于一个任意值的边之后,当前图的连通性是一样的. 于是我们按照权值分开处理,对 ...
- [CF891C] Envy - Kruskal,并查集
给出一个 n 个点 m条边的无向图,每条边有边权,共 Q次询问,每次给出 \(k\)条边,问这些边能否同时在一棵最小生成树上. Solution 所有最小生成树中某权值的边的数量是一定的 加完小于某权 ...
- 题解 [CF891C] Envy
题面 解析 首先根据Kruskal算法, 我们可以知道, 在加入权值为\(w\)的边时, 权值小于\(w\)的边都已经加进树里了(除了连成环的). 所以,我们可以保存一下每条边的端点在加入生成树之前的 ...
- 【题解】CF891CEnvy
[题解] CF891C Envy 很好玩的一道题.尽管不难,但是调了很久QAQ 考虑克鲁斯卡尔最小生成树的算法,可以发现这些最小树生成的性质: 当生成树所有边的权值都\(\le\)某个$ w$的时刻, ...
随机推荐
- Linux服务器安装svn
云安装 yum install subversion 配置 1.配置仓库 [root@localhost /]# cd /home [root@localhost home]# mkdir svn [ ...
- bash: /usr/bin/npm: No such file or directory
一个整得很烂了的Ubuntu服务器, 各种问题乱出. npm老是升不到最新版(一直显示1.4),于是我干脆删了, 结果再去装却装不上了, 如果用apt-get install npm安装, 就得到如下 ...
- swift闭包的另一种用法
这不是教程. 当你碰到函数参数需要传递一个闭包(closure)时,一般是可以直接这么传递的(假定无返回): // 教程一般教你在参数位置传递closure: someMethod(arg1, arg ...
- Uploading File using Ajax and receiving binary data in Asp.net (C#)[转]
基础知识,可由此衍生.原文:http://uniapple.net/blog/?p=2050 In this post, I will show you how to upload a file us ...
- android app rate on google play and amazon
http://stackoverflow.com/questions/11393191/linking-back-to-amazon-app-store-for-ratings public st ...
- BarTender 2016表单中的“秤显示”控件
BarTender 2016中的表单是一个非常实用的工具,它可以实现数据输出提示,查询提示和同一表单的记录选择.这些都离开可供添加的控件,“秤显示”控件也是我们打印尝尝需要涉及的,今天我们就来看看什么 ...
- QT基础:QMainWindow学习小结
简述 普通的桌面应用程序有个共同的特性,有菜单栏.工具栏.状态栏.中央窗口等部件.菜单栏其实可以看成是一个窗口,菜单栏中的每一个菜单也可以看成一个窗口,每个部件基本都可以认为是一个窗口.那么这些典型的 ...
- less语法(一)变量与extend
摘要: 作为 CSS 的一种扩展,Less 不仅完全兼容 CSS 语法,而且连新增的特性也是使用 CSS 语法.这样的设计使得学习 Less 很轻松,而且你可以在任何时候回退到 CSS.less文件是 ...
- MTK 时区修改
1.修改packages/apps/Settings/res/xml-xx-xx/timezones.xml (xx-xx表示不同的语言和区域),添加下面的内容: <!-- timezo ...
- Tree Recovery(前序中序求后序)
Tree Recovery Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14640 Accepted: 9091 De ...