zoukankan      html  css  js  c++  java
  • CodeForces

    For a connected undirected weighted graph G, MST (minimum spanning tree) is a subgraph of G that contains all of G's vertices, is a tree, and sum of its edges is minimum possible.

    You are given a graph G. If you run a MST algorithm on graph it would give you only one MST and it causes other edges to become jealous. You are given some queries, each query contains a set of edges of graph G, and you should determine whether there is a MST containing all these edges or not.

    Input

    The first line contains two integers nm (2  ≤ n, m  ≤ 5·105n - 1 ≤ m) — the number of vertices and edges in the graph and the number of queries.

    The i-th of the next m lines contains three integers uiviwi (ui ≠ vi1 ≤ wi ≤ 5·105) — the endpoints and weight of the i-th edge. There can be more than one edges between two vertices. It's guaranteed that the given graph is connected.

    The next line contains a single integer q (1 ≤ q ≤ 5·105) — the number of queries.

    q lines follow, the i-th of them contains the i-th query. It starts with an integer ki (1 ≤ ki ≤ n - 1) — the size of edges subset and continues with ki distinct space-separated integers from 1 to m — the indices of the edges. It is guaranteed that the sum of ki for 1 ≤ i ≤ q does not exceed 5·105.

    Output

    For each query you should print "YES" (without quotes) if there's a MST containing these edges and "NO" (of course without quotes again) otherwise.

    Example

    Input
    5 7
    1 2 2
    1 3 2
    2 3 1
    2 4 1
    3 4 1
    3 5 2
    4 5 2
    4
    2 3 4
    3 3 4 5
    2 1 7
    2 1 2
    Output
    YES
    NO
    YES
    NO

    Note

    This is the graph of sample:

    Weight of minimum spanning tree on this graph is 6.

    MST with edges (1, 3, 4, 6), contains all of edges from the first query, so answer on the first query is "YES".

    Edges from the second query form a cycle of length 3, so there is no spanning tree including these three edges. Thus, answer is "NO".

    题意:给定N点M点的无向图,M>=N-1,然后给出Q个询问,每个询问给出一个边集,回答这个边集是否存在于一个最小生成树里。

    思路:如果是问一条边,那么我们可以得到最小生成树,然后如果其是树边,或者不超过形成的环的最大边,久说明可以。

    但是这里不算问一条边,而是边集,我们如果按照同样的方法,取验证这些边是否ok,则会出错,因为边集内部也可能出现环。

    我们已经最小生成树的最重要的结论:

          我们按权值给边分类,同一类的边贡献的边的数量是一定的,而且任选其中一种方案,其连通性是相同的。

    假设现在只有一个询问,询问的边集按边权排序,权值相同的一块处理,处理到边权为X的时候,[0,X)的部分已经构造号了,如果把询问里边权为X的加进去会产生环,则说明次询问为“NO”。处理完X,把询问中X部分的并查集撤销,然后把原图X连通。 

    用个时间轴即可用当前的并查集。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define pii pair<int,int>
    #define pb push_back
    #define mp make_pair
    #define F first
    #define S second
    using namespace std;
    const int maxn=500010;
    vector<int>e[maxn];
    vector<pii>G[maxn];
    int u[maxn],v[maxn],w[maxn],,ans[maxn];
    int fa[maxn],t[maxn],tf[maxn],times;
    int find(int x){
        if(x!=fa[x]) fa[x]=find(fa[x]);
        return fa[x];
    }
    int find2(int x){ //时间轴,可撤销。 
        if(t[x]!=times) tf[x]=fa[x],t[x]=times;
        if(x!=tf[x]) tf[x]=find2(tf[x]);
        return tf[x];
    }
    int main()
    {
        int N,M,Q,Mx=0;
        scanf("%d%d",&N,&M);
        rep(i,1,N) fa[i]=i;
        rep(i,1,M){
            scanf("%d%d%d",&u[i],&v[i],&w[i]);
            Mx=max(Mx,w[i]);
            e[w[i]].pb(i);
        }
        scanf("%d",&Q);
        rep(i,1,Q){
            int num; scanf("%d",&num);
            rep(j,1,num){
                int x; scanf("%d",&x);
                G[w[x]].pb(mp(i,x));
            }
        }
        rep(i,1,Mx){
            sort(G[i].begin(),G[i].end());
            int L=G[i].size(),Laxt=0;
            rep(j,0,L-1){ //处理问题 
                int id=G[i][j].F,ed=G[i][j].S;
                a=u[ed],b=v[ed];
                if(id!=Laxt) times++,Laxt=id;    
                a=find2(a); b=find2(b);
                if(a!=b) tf[a]=b;
                else ans[id]=-1;
            }
            L=e[i].size();
            rep(j,0,L-1){ //连通 
                int ed=e[i][j],a=u[ed],b=v[ed];
                a=find(a); b=find(b);
                if(a!=b) fa[a]=b;
            }
        }
        rep(i,1,Q) if(ans[i]==-1) puts("NO"); else puts("YES");
        return 0;
    }
  • 相关阅读:
    Linux操纵体系备份工具Tar运用说明
    Linux琐屑网络设置细致分解
    若何制造Linux系统启动盘2
    RedHatAS5下整合Apache和Tomcat
    移除Linux体系下不需求的效劳
    Linux平安隐患及增强管理的方法1
    Fedora 9 布置好后启动不克不及进入GUI,表现屏表现“Out Of Range"的处理惩罚法子
    Linux和Unix最常用的收集下令
    若何彻底移除编造机Wine模仿程式的图标
    若何制造Linux系统启动盘1
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9545197.html
Copyright © 2011-2022 走看看