hdu 4858 项目管理 图的分块

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858

我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的!
两个节点间可能有多条边,不过一条边的两端必然是不同的节点。
每个节点都有一个能量值。
现在我们要编写一个项目管理软件,这个软件呢有两个操作:
1.给某个项目的能量值加上一个特定值。
2.询问跟一个项目相邻的项目的能量值之和。(如果有多条边就算多次,比如a和b有2条边,那么询问a的时候b的权值算2次)。
Input
第一行一个整数T(1 <= T <= 3),表示测试数据的个数。
然后对于每个测试数据,第一行有两个整数n(1 <= n <= 100000)和m(1 <= m <= n + 10),分别表示点数和边数。
然后m行,每行两个数a和b,表示a和b之间有一条边。
然后一个整数Q。
然后Q行,每行第一个数cmd表示操作类型。如果cmd为0,那么接下来两个数u v表示给项目u的能量值加上v(0 <= v <= 100)。
如果cmd为1,那么接下来一个数u表示询问u相邻的项目的能量值之和。
所有点从1到n标号。
Output
对每个询问,输出一行表示答案。
 
题意描述:如题。
算法分析:由于点很多,我们把图中的点分为重点和轻点。重点的定义:该点的度大于sqrt(n)。然后就分为重点和轻点处理即可。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define inf 0x7fffffff
10 using namespace std;
11 const int maxn=100000+10;
12 
13 int n,m;
14 vector<int> vec[maxn],HG[maxn];
15 int deg[maxn],sum[maxn],value[maxn];
16 
17 int main()
18 {
19     int t ;scanf("%d",&t);
20     while (t--)
21     {
22         scanf("%d%d",&n,&m);
23         for (int i=1 ;i<=n ;i++) vec[i].clear(),deg[i]=0,sum[i]=0,value[i]=0;
24         int a,b;
25         for (int i=1 ;i<=m ;i++)
26         {
27             scanf("%d%d",&a,&b);
28             vec[a].push_back(b);
29             vec[b].push_back(a);
30             deg[a] ++ ;deg[b] ++ ;
31         }
32         int d=(int)sqrt(n);
33         for (int i=1 ;i<=n ;i++)
34         {
35             HG[i].clear();
36             int num=vec[i].size();
37             for (int j=0 ;j<num ;j++)
38             {
39                 int v=vec[i][j];
40                 if (deg[v]>d) HG[i].push_back(v);
41             }
42         }
43         int q,cmd,u,w;
44         scanf("%d",&q);
45         while (q--)
46         {
47             scanf("%d",&cmd);
48             if (cmd==1)
49             {
50                 scanf("%d",&u);
51                 int ans=sum[u];
52                 int num=HG[u].size();
53                 for (int j=0 ;j<num ;j++)
54                     ans += value[HG[u][j] ];
55                 printf("%d\n",ans);
56             }
57             else
58             {
59                 scanf("%d%d",&u,&w);
60                 if (deg[u]<=d)
61                 {
62                     int num=vec[u].size();
63                     for (int j=0 ;j<num ;j++)
64                         sum[vec[u][j] ] += w;
65                 }
66                 else value[u] += w;
67             }
68         }
69     }
70     return 0;
71 }

 

转载于:https://www.cnblogs.com/huangxf/p/4382108.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值