zoukankan      html  css  js  c++  java
  • Codeforces 487E

    传送门

    题意:

    给出一个无向联通图,求一个点不经过重复点可以到达点的最小权值,需要兹瓷修改权值。

    先求点双连通分量,然后缩点,形成一棵树,每个新点的权值是其中所有点的最小权值。

    然额,割点属于多个点双连通分量,每次直接修改会TLE(一棵菊花树就可以做到),

    所以对每个点双新建一个结点,对属于它的点连边,这样每个原来的点的父亲一定是它所属的点双。

    之后对每个点双建一个multiset维护最小值,查询时用树链剖分加线段树。

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <set>
      5 using namespace std;
      6 #define maxn 100001
      7 template<typename __>
      8 inline void read(__ &s)
      9 {
     10     char ch;
     11     for(ch=getchar(),s=0;ch<'0'||ch>'9';ch=getchar());
     12     for(;ch>='0'&&ch<='9';ch=getchar())
     13         s=s*10+ch-'0';
     14 }
     15 struct edge
     16 {
     17     int u,v,nex;
     18 }e[maxn<<1];
     19 int pr[maxn],cnt;
     20 void add(int u,int v)
     21 {
     22     e[++cnt]=(edge){u,v,pr[u]};
     23     pr[u]=cnt;
     24     e[++cnt]=(edge){v,u,pr[v]};
     25     pr[v]=cnt;
     26 }
     27 int n,m,bcc_cnt,bcc_dfn,top,q;
     28 int dfn[maxn],low[maxn],cut[maxn<<1];
     29 int s[maxn],belong[maxn<<1],st[maxn];
     30 multiset<int>mst[maxn];
     31 class seg
     32 {
     33 public:
     34     struct edge
     35     {
     36         int u,v,nex;
     37     }e[maxn<<2];
     38     int cnt,dfn,N;
     39     int siz[maxn<<1],depth[maxn<<1],top[maxn<<1],pr[maxn<<1];
     40     int son[maxn<<1],fa[maxn<<1],L[maxn<<1],quit[maxn<<1];
     41     bool vis[maxn<<1];
     42     multiset<int>::iterator it;
     43     void add(int u,int v)
     44     {
     45         e[++cnt]=(edge){u,v,pr[u]};
     46         pr[u]=cnt;
     47         e[++cnt]=(edge){v,u,pr[v]};
     48         pr[v]=cnt;
     49     }
     50     void dfs_make(int u)
     51     {
     52         int v;
     53         siz[u]=vis[u]=1;
     54         for(int i=pr[u];i;i=e[i].nex)
     55         {
     56             v=e[i].v;
     57             if(!vis[v])
     58             {
     59                 depth[v]=depth[u]+1;
     60                 fa[v]=u;
     61                 dfs_make(v);
     62                 siz[u]+=siz[v];
     63                 if(siz[v]>siz[son[u]])
     64                     son[u]=v;
     65             }
     66         }
     67     }
     68     void dfs_lines(int u,int f)
     69     {
     70         int v;
     71         vis[u]=1;
     72         L[u]=++dfn;
     73         quit[dfn]=u;
     74         top[u]=f;
     75         if(son[u])
     76             dfs_lines(son[u],f);
     77         for(int i=pr[u];i;i=e[i].nex)
     78         {
     79             v=e[i].v;
     80             if(!vis[v])
     81                 dfs_lines(v,v);
     82         }
     83     }
     84     struct node
     85     {
     86         int minn;
     87     }tree[maxn<<3];
     88     #define lson id<<1,l,mid
     89     #define rson id<<1|1,mid+1,r
     90     #define INF 0x7fffffff
     91     inline void pushup(int id)
     92     {
     93         tree[id].minn=min(tree[id<<1].minn,tree[id<<1|1].minn);
     94     }
     95     void build(int id,int l,int r)
     96     {
     97         if(l==r)
     98         {
     99             tree[id].minn=s[quit[l]];
    100             return ;
    101         }
    102         int mid=(l+r)>>1;
    103         build(lson);
    104         build(rson);
    105         pushup(id);
    106     }
    107     int query(int id,int l,int r,int L,int R)
    108     {
    109         if(L<=l&&r<=R)
    110             return tree[id].minn;
    111         int mid=(l+r)>>1;
    112         if(R<=mid)
    113             return query(lson,L,R);
    114         else
    115             if(L>mid)
    116                 return query(rson,L,R);
    117             else
    118                 return min(query(lson,L,mid),query(rson,mid+1,R));
    119     }
    120     void update(int id,int l,int r,int pos,int val)
    121     {
    122         if(l==r)
    123         {
    124             tree[id].minn=val;
    125             return ;
    126         }
    127         int mid=(l+r)>>1;
    128         if(pos<=mid)
    129             update(lson,pos,val);
    130         else
    131             update(rson,pos,val);
    132         pushup(id);
    133     }
    134     int query(int u,int v)
    135     {
    136         int ans=INF;
    137         while(top[u]!=top[v])
    138         {
    139             if(depth[top[u]]<depth[top[v]])
    140                 swap(u,v);
    141             ans=min(ans,query(1,1,N,L[top[u]],L[u]));
    142             u=fa[top[u]];
    143         }
    144         if(depth[u]>depth[v])
    145             swap(u,v);
    146         ans=min(ans,query(1,1,N,L[u],L[v]));
    147         if(u>n)
    148             ans=min(ans,s[fa[u]]);
    149         return ans;
    150     }
    151     void init()
    152     {
    153         N=bcc_cnt;
    154         dfs_make(1);
    155         memset(vis,0,sizeof(vis));
    156         dfs_lines(1,1);
    157         for(int i=1;i<=n;i++)
    158             if(fa[i]>n)
    159                 mst[fa[i]-n].insert(s[i]);
    160         for(int i=n+1;i<=N;i++)
    161         {
    162             it=mst[i-n].begin();
    163             s[i]=*it;
    164         }
    165         build(1,1,N);
    166     }
    167     void change(int pos,int val)
    168     {
    169         int p=fa[pos]-n;
    170         if(p>0)
    171         {
    172             it=mst[p].find(s[pos]);
    173             mst[p].erase(it);
    174             mst[p].insert(val);
    175             it=mst[p].begin();
    176             s[fa[pos]]=(*it);
    177             update(1,1,N,L[fa[pos]],s[fa[pos]]);
    178         }
    179         update(1,1,N,L[pos],val);
    180         s[pos]=val;
    181     }
    182 }T;
    183 int find_fa(int x)
    184 {
    185     if(belong[x]==x)
    186         return x;
    187     return belong[x]=find_fa(belong[x]);
    188 }
    189 void UN(int x,int y)
    190 {
    191     int xx=find_fa(x),yy=find_fa(y);
    192     if(xx!=yy)
    193         belong[xx]=yy;
    194 }
    195 void tarjan(int u,int f)
    196 {
    197     int num=0,k,v;
    198     st[++top]=u;
    199     dfn[u]=low[u]=++bcc_dfn;
    200     for(int i=pr[u];i;i=e[i].nex)
    201     {
    202         v=e[i].v;
    203         if(!dfn[v])
    204         {
    205             tarjan(v,u);
    206             low[u]=min(low[u],low[v]);
    207             if(low[v]>=dfn[u])
    208             {
    209                 cut[u]=1;
    210                 ++bcc_cnt;
    211                 do
    212                 {
    213                     k=st[top--];
    214                     T.add(k,bcc_cnt);
    215                     UN(bcc_cnt,k);
    216                 }while(k!=v);
    217                 T.add(u,bcc_cnt);
    218                 UN(u,bcc_cnt);
    219             }
    220         }
    221         else
    222             if(v!=f)
    223                 low[u]=min(low[u],dfn[v]);
    224     }
    225 }
    226 int main()
    227 {
    228     read(n);
    229     read(m);
    230     read(q);
    231     int u,v,i,j;
    232     for(i=1;i<=n;i++)
    233         read(s[i]);
    234     for(i=1;i<=m;i++)
    235     {
    236         read(u);
    237         read(v);
    238         add(u,v);
    239     }
    240     bcc_cnt=n;
    241     tarjan(1,0);
    242     for(i=1;i<=n;i++)
    243         if(cut[i])
    244             for(j=pr[i];j;j=e[j].nex)
    245                 if(cut[e[j].v]&&find_fa(i)!=find_fa(e[j].v))
    246                 {
    247                     ++bcc_cnt;
    248                     T.add(i,bcc_cnt);
    249                     T.add(e[j].v,bcc_cnt);
    250                 }
    251     T.init();
    252     char op[2];
    253     for(i=1;i<=q;i++)
    254     {
    255         scanf("%s",op);
    256         read(u);
    257         read(v);
    258         if(op[0]=='A')
    259             printf("%d
    ",T.query(u,v));
    260         else
    261             T.change(u,v);
    262     }
    263 }
    codeforces 487E

    偏偏出现在最后的补充说明:

    如果两个点的LCA是一个新建结点,那LCA的fa也是一个属于该点的割点,修改时也要修改。

  • 相关阅读:
    DAY1 linux 50条命令
    安卓2.0,3.0,4.0的差别
    java历史
    晶体管共射极单管放大电路
    jquery取消选择select下拉框
    oarcle数据库导入导出,创建表空间
    360chrome,google chrome浏览器使用jquery.ajax加载本地html文件
    jquery 选择器
    nodejs 相关
    关于http请求
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7689211.html
Copyright © 2011-2022 走看看