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
原文地址:https://www.cnblogs.com/starve/p/10864724.html