• zoj 3261 逆向并查集+离线处理


    题意:给出一些点,每个点有权值,然后有一些边,相连。无向的。然后有一些操作

    链接:点我

    query a.表示从a出发的能到达的所有点权值最大的点的编号(相同取编号最小,而且权值要比自己大)

    destory a,b 表示删除连接a,b的边

    逆向并查集。

    把没有删除的边先加入并查集,一个集合内表示连通的,根结点为权值最大的点。

    然后对于查询离线读入,从最后开始操作,对于删除的点,然后重新加入到并查集中,更新最值。

    查询的时候便是查询根结点的值是否大于自身的值

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <map>
      6 using namespace std;
      7 
      8 const int MAXN=10010;
      9 int F[MAXN];
     10 int p[MAXN];
     11 int val[MAXN];//最大值的下标
     12 int num[MAXN];//最大值
     13 int find(int x)
     14 {
     15     if(F[x]==-1)return x;
     16     return F[x]=find(F[x]);
     17 }
     18 void bing(int u,int v)
     19 {
     20     int t1=find(u),t2=find(v);
     21     if(t1!=t2)
     22     {
     23         F[t1]=t2;
     24         if(num[t1]>num[t2])
     25         {
     26             num[t2]=num[t1];
     27             val[t2]=val[t1];
     28         }
     29         else if(num[t1]==num[t2] && val[t2]>val[t1])
     30             val[t2]=val[t1];
     31     }
     32 }
     33 map<int,int>mp[MAXN];
     34 struct Edge
     35 {
     36     int u,v;
     37 }edge[20010];
     38 bool used[20010];
     39 struct Node
     40 {
     41     int op;
     42     int u,v;
     43 }node[50010];
     44 int ans[50010];
     45 char str[20];
     46 int main()
     47 {
     48     int n;
     49     int Q;
     50     int m;
     51     int u,v;
     52     bool first=true;
     53     while(scanf("%d",&n)==1)
     54     {
     55         if(first)first=false;
     56         else printf("
    ");
     57         memset(F,-1,sizeof(F));
     58         for(int i=0;i<n;i++)
     59         {
     60             scanf("%d",&p[i]);
     61             val[i]=i;
     62             num[i]=p[i];
     63             mp[i].clear();
     64         }
     65 
     66         scanf("%d",&m);
     67         for(int i=0;i<m;i++)
     68         {
     69             scanf("%d%d",&u,&v);
     70             if(u>v)swap(u,v);
     71             mp[u][v]=i;
     72             edge[i].u=u;
     73             edge[i].v=v;
     74             used[i]=false;
     75         }
     76         scanf("%d",&Q);
     77         for(int i=0;i<Q;i++)
     78         {
     79             scanf("%s",&str);
     80             if(str[0]=='q')
     81             {
     82                 node[i].op=0;
     83                 scanf("%d",&node[i].u);
     84             }
     85             else
     86             {
     87                 node[i].op=1;
     88                 scanf("%d%d",&u,&v);
     89                 if(u>v)swap(u,v);
     90                 node[i].u=u;
     91                 node[i].v=v;
     92                 int tmp=mp[u][v];
     93                 used[tmp]=true;
     94             }
     95         }
     96         for(int i=0;i<m;i++)    //没有拆的点连上
     97           if(!used[i])
     98           {
     99               bing(edge[i].u,edge[i].v);
    100           }
    101         int cnt=0;
    102         for(int i=Q-1;i>=0;i--)
    103         {
    104             if(node[i].op==0)
    105             {
    106                 u=node[i].u;
    107                 int t1=find(u);
    108                 if(num[t1]>p[u])ans[cnt++]=val[t1];
    109                 else ans[cnt++]=-1;
    110             }
    111             else
    112             {
    113                 bing(node[i].u,node[i].v);
    114             }
    115         }
    116         for(int i=cnt-1;i>=0;i--)printf("%d
    ",ans[i]);
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    实验三:Linux进程管理(HDU)
    ORA-25153错误及解决办法
    Python中的next()iter()函数详解
    python基础_格式化输出(%用法和format用法)(转载)
    DataTable ---导出Excel
    gridview-
    Web-Web/Json的请求与返回
    Sql-事务
    Windows-远程桌面
    Dev-GridView-对于gridview的列值的合计
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4487753.html
Copyright © 2020-2023  润新知