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 }
时间: 2024-10-18 08:40:13

hdu 4858 项目管理 图的分块的相关文章

hdu 4858 项目管理 图分治 (复合算法)

hdu 4858 项目管理 题意:给n(<=100000)个点,m条边( <=n+10),可能有重边,每个点有个值val,初识为0. 2种操作. 操作1:点x的值,加addx. 操作2:输出x点的邻点的val和. 分析:简单的优化操作1或操作2是不行的. 法一:针对点的度将图中点分为两类点.对于度大于sqrt (n)的点为重点,对于小于等于sqrt(n)的点为轻点. 重点的个数小于sqrt(n)个.针对重点和轻点分别处理. 法二:也可考虑每个点,将其邻点分类.大于该点度的点分为一类,等于该点的

hdu 4858 项目管理 (图的分治)

项目管理 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 252    Accepted Submission(s): 88 Problem Description 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的! 两个节点间可能有多条边,不过一条边的两端必然是不同的节点. 每个节点都有一个能量值. 现

hdu 4858 项目管理(vector模拟)

# include <stdio.h> # include <algorithm> # include <string.h> # include <vector> # define N 100005 using namespace std; vector<int>g[N]; int node[N]; int slove(int x) { int sum=0,i; for(i=0;i<g[x].size();i++) { sum+=node[

HDU 4858 项目管理(邻接表 暴力模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的! 两个节点间可能有多条边,不过一条边的两端必然是不同的节点.每个节点都有一个能量值. 现在我们要编写一个项目管理软件,这个软件呢有两个操作:1.给某个项目的能量值加上一个特定值.2.询问跟一个项目相邻的项目的能量值之和.(如果有多条边就算多次,比如a和b有2条边,那么询问a的时候b的权值算2次). 解题报告:这个

hdu 4858 项目管理

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 题意:中文不解释 解法:直接按题意模拟一遍,数据水? 代码: #include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> #include<ctype.h> #include<algorithm> #include<vector> #i

hdu 4858 项目管理(STL集装箱)

项目管理 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 730    Accepted Submission(s): 258 Problem Description 我们建造了一个大项目! 这个项目有n个节点,用非常多边连接起来.而且这个项目是连通的! 两个节点间可能有多条边,只是一条边的两端必定是不同的节点. 每一个节点都有一个能量

图的分块

例1. hdu 4858 项目管理 按点的度数划分为重点(deg>=sqrt(m))和轻点(deg<sqrt(m)), 轻点暴力更新, 重点只更新邻接的重点 #include <iostream> #include <algorithm> #include <math.h> #include <cstdio> #include <vector> #define pb push_back #define REP(i,a,n) for(i

BestCoder Round #1 1002 项目管理 (HDU 4858)

项目管理 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 738    Accepted Submission(s): 260 Problem Description 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的!两个节点间可能有多条边,不过一条边的两端必然是不同的节点.每个节点都有一个能量值. 现在我

HDOJ 4858 项目管理

暴力... 项目管理 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 537    Accepted Submission(s): 189 Problem Description 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的! 两个节点间可能有多条边,不过一条边的两端必然是不同的节点. 每个节点都有一