zoukankan      html  css  js  c++  java
  • Codeforces891C. Envy

    $n leq 5e5$,$m leq 5e5$的无向边权图,$q leq 5e5$个询问,每次问一系列边是否能同时存在于某棵最小生成树上。

    一条边在最小生成树上,当比他小的边都加入后,加入他会使连通块数-1,也就是他两端的点在加入比他小的所有边后仍不在一起。

    于是乎把所有询问的所有边排序,每次处理一个询问的一种边,新开一个并查集看看把这个询问的边加进去之后会不会有一条边是废的(没使连通块数-1,也就是两端点的并查集父亲相同)。

     1 //#include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<vector>
     6 //#include<queue>
     7 //#include<time.h>
     8 //#include<complex>
     9 #include<algorithm>
    10 #include<stdlib.h>
    11 using namespace std;
    12 
    13 int n,m,lq;
    14 #define maxn 500011
    15 struct Edge{int from,to,v;}edge[maxn];
    16 int ufs[maxn],vis[maxn],ufsb[maxn];
    17 int find(int x) {return ufs[x]==x?x:(ufs[x]=find(ufs[x]));}
    18 int findb(int Time,int x) {return vis[x]==Time?(ufsb[x]==x?x:(ufsb[x]=findb(Time,ufsb[x]))):(vis[x]=Time,(ufsb[x]=find(x)));}
    19 
    20 bool ans[maxn];
    21 struct vnode{int id,e;};
    22 vector<vnode> v[maxn],ve[maxn];
    23 
    24 int main()
    25 {
    26     scanf("%d%d",&n,&m); int maxv=0;
    27     for (int i=1,x,y,val;i<=m;i++) scanf("%d%d%d",&x,&y,&val),maxv=max(maxv,val),
    28     edge[i]=(Edge){x,y,val},ve[val].push_back((vnode){x,y});
    29     
    30     scanf("%d",&lq);
    31     for (int i=1,x,y;i<=lq;i++)
    32     {
    33         scanf("%d",&x);
    34         while (x--) scanf("%d",&y),v[edge[y].v].push_back((vnode){i,y});
    35     }
    36     
    37     for (int i=1;i<=n;i++) ufs[i]=i;
    38     int Time=0;
    39     for (int i=1;i<=maxv;i++)
    40     {
    41         for (int j=0,last=0,to=v[i].size();j<to;j++)
    42         {
    43             int id=v[i][j].id,x=edge[v[i][j].e].from,y=edge[v[i][j].e].to;
    44             if (last!=id) ++Time;
    45             if (vis[x]!=Time) vis[x]=Time,ufsb[x]=find(x);
    46             if (vis[y]!=Time) vis[y]=Time,ufsb[y]=find(y);
    47             if (findb(Time,x)==findb(Time,y)) ans[id]=1;
    48             ufsb[ufsb[x]]=ufsb[y];
    49             last=id;
    50         }
    51         for (int j=0,to=ve[i].size();j<to;j++)
    52         {
    53             int x=find(ve[i][j].id),y=find(ve[i][j].e);
    54             if (x!=y) ufs[x]=y;
    55         }
    56     }
    57     for (int i=1;i<=lq;i++) puts(ans[i]?"NO":"YES");
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    HDU 4221 Greedy?(贪心)
    HDU 3400 Line belt (三分法)
    POJ 1026 Cipher(置换)
    POJ 1166 The Clocks(暴搜)
    HDU 4122 Alice's mooncake shop(RMQ,或者单调队列)
    POJ 1721 CARDS(置换)
    POJ 3270 Cow Sorting(置换)
    高斯消元法(模板)
    http://blog.seirsoft.com
    转载 STL容器的erase用法
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8640642.html
Copyright © 2011-2022 走看看