Graph

Problem Description

P. T. Tigris is a student currently studying graph theory. One day, when he was studying hard, GS appeared around the corner shyly and came up with a problem:
Given a graph with n nodes and m undirected weighted edges, every node having one of two colors, namely black (denoted as 0) and white (denoted as 1), you’re to maintain q operations of either kind:

* Change x: Change the color of x
th node. A black node should be changed into white one and vice versa.

* Asksum A B: Find the sum of weight of those edges whose two end points are in color A and B respectively. A and B can be either 0 or 1.

P. T. Tigris doesn’t know how to solve this problem, so he turns to you for help.
 
Input
There are several test cases.

For each test case, the first line contains two integers, n and m (1 ≤ n,m ≤ 10
5), where n is the number of nodes and m is the number of edges.

The second line consists of n integers, the i
th of which represents the color of the i
th node: 0 for black and 1 for white.

The following m lines represent edges. Each line has three integer u, v and w, indicating there is an edge of weight w (1 ≤ w ≤ 2
31 - 1) between u and v (u != v).

The next line contains only one integer q (1 ≤ q ≤ 10
5), the number of operations.

Each of the following q lines describes an operation mentioned before.

Input is terminated by EOF.
 
Output
For each test case, output several lines.

The first line contains “Case X:”, where X is the test case number (starting from 1).

And then, for each “Asksum” query, output one line containing the desired answer.
 
Sample Input
4 3
0 0 0 0
1 2 1
2 3 2
3 4 3
4
Asksum 0 0
Change 2
Asksum 0 0
Asksum 0 1
4 3
0 1 0 0
1 2 1
2 3 2
3 4 3
4
Asksum 0 0
Change 3
Asksum 0 0
Asksum 0 1
 
Sample Output
Case 1:
6
3
3
Case 2:
3
0
4
这题是很好的题啊,题目意思就是,给一些点,都是0或1,找两边是00 01 11的边权合,这题的关键就是有的边很多,如果我们就用暴力,那么复杂度必然是p*n,其实,想想问题的关键,就是有的点相连的边太多了,这样暴力会超时,比赛的时候,也是这个问题,虽然有点想法,但当时由于时间太短,不能写出来,下来要想了很长时间,我们要把有很多的边标记下,特殊处理,这样,我们不就能省掉很多时间了么?基于,这样的想法,我们,就可以这样做,把超过界限的点,标记成超极点,其他的就是普通点,我们连接超极点和超极点,普通点与普通点。超极点,但是,超极点不连接普通点!对于超极点,我们用一个数组,保存它周围的0和1的点的权和,这样我们就可以用0(1)的时间,快速维护最终的结果,对于普通点,我们就暴力维护就可以了,因为他周围的点少,时间就可以大大的省下来!这样的想法很好,复杂度是多少呢?我们可以发现,如果我们把办限定为sqrt(m),那么超极点的个数一定不会多于2*sqrt(m),这一点很好证明,那么这样,所有点的暴力维护的值都是sqrt(m)了,那么复杂度就是n*sqrt(m),当然,这是可以过了的,这种思想很有用,也很神奇啊,当时,有点影子,但没有时间,来实现了!对于本题一定要注意重边的情况和一定要用--int64,好了,到这里,就可以a了!还有一点小技巧,见代码!
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
#define MAXN 100005
struct nodeedge{
int s,e;
__int64 val;
}edge[40*MAXN];
struct nodelist{
int next,to,flag;
}l[200*MAXN];
char str[300];
int head[MAXN],p[MAXN],index[MAXN],limit;//判定是否是超极点
__int64 sum[3],sumsuper[MAXN][2];
void change(int x)
{
int i,j;
int temp=p[x]^1,t; for(j=head[x];j!=-1;j=l[j].next)
{
i=l[j].to;
sum[p[x]+p[i]]-=edge[j].val;
sum[temp+p[i]]+=edge[j].val;
if((!l[x].flag)&&l[i].flag)
{
sumsuper[i][p[x]]-=edge[j].val;
sumsuper[i][temp]+=edge[j].val;
}
}
if(l[x].flag)
{
sum[p[x]]-=sumsuper[x][0];
sum[temp]+=sumsuper[x][0];
sum[p[x]+1]-=sumsuper[x][1];
sum[temp+1]+=sumsuper[x][1];
}
p[x]=p[x]^1;//取反
}
void build(int i,int s,int e,__int64 val)//建邻接表
{
if(l[s].flag&&(!l[e].flag))
{
sumsuper[s][p[e]]+=val;
}
else
{
l[i].next=head[s];
l[i].to=e;
head[s]=i;
}
}
bool cmp(nodeedge a,nodeedge b)
{
if(a.s != b.s)
return a.s < b.s;
else
return a.e < b.e;
}
int main ()
{
int n,m,i,edgem,m2,asnum,a1,a2,tcase;
tcase=1;
while(scanf("%d%d",&n,&m)!=EOF)
{
limit=350;m2=2*m;
sum[0]=sum[1]=sum[2]=0;
for(i=1;i<=n;i++)
{
scanf("%d",&p[i]);
index[i]=0;head[i]=-1;
}
for(i=1;i<=m;i++)
{
scanf("%d%d%I64d",&edge[i].s,&edge[i].e,&edge[i].val);
edge[i+m].s=edge[i].e,edge[i+m].e=edge[i].s,edge[i+m].val=edge[i].val;//建反向边
sum[p[edge[i].s]+p[edge[i].e]]+=edge[i].val;
}
sort(edge+1,edge+m2+1,cmp);//边从1开始计数
edgem=1;
for(i=2;i<=m2;i++)//去掉重边
{
if((edge[i].s==edge[edgem].s)&&(edge[i].e==edge[edgem].e))
{
edge[edgem].val+=edge[i].val;
}
else{
edgem++;
edge[edgem]=edge[i];
}
}
for(i=1;i<=edgem;i++)
{
index[edge[i].s]++;
}
for(i=1;i<=n;i++)//统计超极结点
{
if(index[i]>=limit)
{
l[i].flag=1;//是超极结点
sumsuper[i][0]=sumsuper[i][1]=0;
} else
l[i].flag=0;
} for(i=1;i<=edgem;i++)//建领接表
{
build(i,edge[i].s,edge[i].e,edge[i].val);
}
scanf("%d",&asnum);
printf("Case %d:\n",tcase++);
while(asnum--)
{
scanf("%s",str);
if(str[0]=='A')
{
scanf("%d%d",&a1,&a2);
printf("%I64d\n",sum[a1+a2]);
}
else{
scanf("%d",&a1);
change(a1);
}
} }
return 0;
}

hdu4467 Graph的更多相关文章

  1. HDU4467:Graph(点的度数分块)

    传送门 题意 给出一张n个点m条边的无向图,点的颜色为0/1,每次有两种操作: 1.Asksum x y,查询两点颜色为x和y的边的权值之和 2.Change x,将x颜色取反 分析 最直接的做法是每 ...

  2. HDU4467 Graph【轻重点维护】

    HDU4467 Graph 题意: 给出一张染色图,\(n\)个点每个点是黑色或者白色,\(m\)条带权边,\(q\)次操作,有两种操作: 改变一个点的颜色 问所有边中两个端点的颜色为给定情况的边权和 ...

  3. [开发笔记] Graph Databases on developing

    TimeWall is a graph databases github It be used to apply mathematic model and social network with gr ...

  4. Introduction to graph theory 图论/脑网络基础

    Source: Connected Brain Figure above: Bullmore E, Sporns O. Complex brain networks: graph theoretica ...

  5. POJ 2125 Destroying the Graph 二分图最小点权覆盖

    Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8198   Accepted: 2 ...

  6. [LeetCode] Number of Connected Components in an Undirected Graph 无向图中的连通区域的个数

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  7. [LeetCode] Graph Valid Tree 图验证树

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  8. [LeetCode] Clone Graph 无向图的复制

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...

  9. 讲座:Influence maximization on big social graph

    Influence maximization on big social graph Fanju PPT链接: social influence booming of online social ne ...

随机推荐

  1. vs-code 配置

    vs-code 快键键 命令面板 ctrl+shift+p vs-code 相关插件 AutoFileName Chinese (Simplified) Language Pack for Visua ...

  2. Hibernate延迟加载策略

    所谓懒加载(lazy)就是延时加载,就是当在真正需要数据的时候,才真正执行数据加载操作 至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限 ,为了减少并发量, ...

  3. 【API】NetUserEnum-获取系统所有账户名称

    1 说明 该NetUserEnum函数检索服务器上所有用户帐户的信息. 函数原型: NET_API_STATUS NetUserEnum( _In_ LPCWSTR servername, _In_ ...

  4. 『记录』Android参考资料

    欢迎留言推荐好的教程.资料.博客及作者等. 『记录』Android参考资料 1.前期环境 Android Studio使用Git Android Studio快捷键总结 Android Studio及 ...

  5. Project Euler Problem2

    Even Fibonacci numbers Problem 2 Each new term in the Fibonacci sequence is generated by adding the ...

  6. com.alibaba.fastjson.JSONException: autoType is not support.

    解决办法:https://github.com/alibaba/fastjson/wiki/enable_autotype 文摘如下: 一.添加autotype白名单 添加白名单有三种方式,三选一,如 ...

  7. 二、vue中组件的使用

    1.组件拆分 1.组件实质上也是一个vue实例,因此组件中也可以使用vue的对象属性,反过来每一个vue实例也是一个vue组件(注:1.唯一不同的是el是根实例的特有选项,2.组件中的data必须是一 ...

  8. 深度剖析:PHP中json_encode与json_decode

    一.json_encode() 对变量进行JSON编码, 语法: json_encode ( $value [, $options = 0 ] ) 注意:1.$value为要编码的值,且该函数只对UT ...

  9. 【LOJ】#2496. 「AHOI / HNOI2018」毒瘤

    题面 还有这么诚实的出题人! 我们最多影响20个点,然后把这20个点的虚树建出来,并且枚举每个点的选举状态,如果一个点选或不选可以通过改\(dp[u][0] = 0\)或\(dp[u][1] = 0\ ...

  10. ubuntu16耳机没声音解决

    装完ubuntu16后又装了英伟达的显卡驱动,安装了网易云音乐后,突然发现电脑没声音,使用了如下方法解决 首先用在终端输入如下命令,下载pulseaudio音量控制软件 sudo apt instal ...