• hdu4467 graph


    莫队+重点轻点

    题意:给你n个点(每个点都有一个颜色,0代表黑色,1代表白色),m条边,每条边有一个权值.现在有有两个操作,一个是修改某个点的颜色(白变成黑/黑变成白),另外一个是询问那些边的两个端点都为指定颜色的权值总和

    分析:将所有点分为重点和轻点,但是这次重点和重点之前的边要建在一个图中,剩余的边要建在另一个图中。对于最后访问的颜色,只有三种情况黑+黑(求和为0),黑+白(求和为1),白+白(求和为2),所以用a[0],a[1],a[2]分别对应的答案。对于重点i设置一个sum[i][2],sum[i][0]表示所有与他相邻且颜色为0(黑)的点的边权之和,sum[i][1]同理。更新时,对于重点i来说拿sum[i][0]和sum[i][1]去直接更新a数组,同时将其相邻的重点的sum值进行修改。而对于轻点i来说,遍历所有与i相连的边,暴力更新a数组,而当其相邻点为重点时则需要更新一下重点的sum数组。对于查询操作,直接输出a数组中的值即可

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 #include<cmath>
      7 using namespace std;
      8 const int M=1e5+10;
      9 typedef long long ll;
     10 struct node{
     11     ll u,v,w;
     12 }a[M];
     13 bool cmp(node p,node q){
     14     if(p.u==q.u)
     15         return p.v<q.v;
     16     return p.u<q.u;
     17 }
     18 struct node1{
     19     ll id,w;
     20     node1(ll id1=0,ll w1=0):id(id1),w(w1){
     21     }
     22 };
     23 vector<node1>g1[M],g2[M];
     24 ll n,m,in[M],zhong[M],sum[M][3],ans[4],col[M];
     25 char s[10];
     26 int main(){
     27     ll sign=1;
     28     while(scanf("%lld%lld",&n,&m)!=EOF){
     29         for(int i=1;i<=n;i++){
     30             g1[i].clear();
     31             g2[i].clear();
     32             zhong[i]=0;
     33             in[i]=0;
     34             sum[i][0]=sum[i][1]=0;
     35         }
     36         memset(ans,0,sizeof(ans));
     37         //ans[0]=ans[1]=ans[2]=0;
     38         for(int i=1;i<=n;i++)
     39             scanf("%lld",&col[i]);
     40         for(int i=1;i<=m;i++){
     41             scanf("%lld%lld%lld",&a[i].u,&a[i].v,&a[i].w);
     42             if(a[i].u>a[i].v)
     43                 swap(a[i].u,a[i].v);
     44             ans[col[a[i].u]+col[a[i].v]]+=a[i].w;
     45         }
     46         sort(a+1,a+1+m,cmp);
     47         ll cnt=0;
     48         int i,j;
     49         //将重边加在一起; 
     50         for(i=1;i<=m;i=j){
     51             for(j=i+1;j<=m;j++)
     52                 if(a[i].u==a[j].u&&a[i].v==a[j].v){
     53                     a[i].w+=a[j].w;
     54                 }
     55                 else
     56                     break;
     57             a[++cnt]=a[i];
     58         }
     59         ll N=(int)sqrt(cnt);
     60         for(i=1;i<=cnt;i++){
     61             in[a[i].u]++;
     62             in[a[i].v]++;
     63         }
     64         for(i=1;i<=n;i++){
     65             if(in[i]>N)
     66                 zhong[i]=1;
     67         }
     68         for(i=1;i<=cnt;i++){
     69             ll u=a[i].u,v=a[i].v,w=a[i].w;
     70             if(zhong[u]){
     71                 if(zhong[v]){
     72                     g1[u].push_back(node1(v,w));
     73                     g1[v].push_back(node1(u,w));
     74                     sum[u][col[v]]+=w;
     75                     sum[v][col[u]]+=w;
     76                 }
     77                 else{
     78                     g2[v].push_back(node1(u,w));
     79                     sum[u][col[v]]+=w;
     80                 }
     81             }
     82             else{
     83                 if(zhong[v]){
     84                     g2[u].push_back(node1(v,w));
     85                     sum[v][col[u]]+=w;
     86                 }
     87                 else{
     88                     g2[u].push_back(node1(v,w));
     89                     g2[v].push_back(node1(u,w));
     90                 }
     91             }
     92         }
     93         ll P;
     94         printf("Case %lld:
    ",sign++);
     95         scanf("%lld",&P);
     96         
     97         
     98         while(P--){
     99             scanf("%s",s);
    100             if(s[0]=='A'){
    101                 int x,y;
    102                 scanf("%d%d",&x,&y);
    103                 printf("%lld
    ",ans[x+y]);
    104             }
    105             else{
    106                 int x;
    107                 scanf("%d",&x);
    108                 if(zhong[x]){
    109                     ans[col[x]+0]-=sum[x][0];
    110                     ans[col[x]+1]-=sum[x][1];
    111                     ans[1-col[x]+0]+=sum[x][0];
    112                     ans[1-col[x]+1]+=sum[x][1];
    113                     for(i=0;i<g1[x].size();i++){
    114                         ll v=g1[x][i].id,w=g1[x][i].w;
    115                         sum[v][col[x]]-=w;
    116                         sum[v][1-col[x]]+=w;
    117 
    118                     }
    119                 }
    120                 else{
    121                     for(i=0;i<g2[x].size();i++){
    122                         ll v=g2[x][i].id,w=g2[x][i].w;
    123                         ans[col[x]+col[v]]-=w;
    124                         ans[1-col[x]+col[v]]+=w;
    125                         if(zhong[v]){
    126                             sum[v][col[x]]-=w;
    127                             sum[v][1-col[x]]+=w;
    128                         }
    129                     }
    130                 }
    131                 col[x]=1-col[x];
    132             }
    133         }
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    .NET:在ASP.NET中如何进行IP限制
    vim配置文件和插件
    初学Perl的感受之数据类型
    ASP.NET伪静态详解及配置
    Wayback Machine
    对单元测试的一点感悟——这是一把双刃剑
    python中使用postgres
    第三章 匿名方法
    在C#程序中使用ocx的方法
    可扩展的 “密码强度” 代码示例
  • 原文地址:https://www.cnblogs.com/starve/p/10864724.html
Copyright © 2020-2023  润新知