hdu 3038(How Many Answers Are Wrong)+3047(Zjnu Stadium)(种类并查集)
来源:互联网 发布:阿姆斯特丹大学 知乎 编辑:程序博客网 时间:2024/09/21 08:47
hdu 3038:http://acm.hdu.edu.cn/showproblem.php?pid=3038
hdu 3047:http://acm.hdu.edu.cn/showproblem.php?pid=3047
如果之前没见过种类并查集的话,估计第一反应都是线段树吧...
这两道题都是在压缩路径的时候,利用递归,求得节点到根的距离。
用sum[i]表示节点i到根节点的距离,f[i]记录i的根节点。
f[rb]=ra;
sum[rb]=sum[a]-sum[b]+c;()
hdu 3038 代码(去掉注释那行可以秒过3047):
#include <limits.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <algorithm>#include <iostream>#include <iterator>#include <sstream>#include <queue>#include <stack>#include <string>#include <vector>#include <list>#include <set>//#define ONLINE_JUDGE#define eps 1e-6#define INF 0x7fffffff //INT_MAX#define inf 0x3f3f3f3f //int??????????????????#define FOR(i,a) for((i)=0;i<(a);(i)++) //[i,a);#define MEM(a) (memset((a),0,sizeof(a)))#define sfs(a) scanf("%s",a)#define sf(a) scanf("%d",&a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define pfs(a) printf("%s\n",a)#define sfd(a,b) scanf("%d%d",&a,&b)#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)#define for1(i,a,b) for(int i=(a);i<b;i++)#define for2(i,a,b) for(int i=(a);i<=b;i++)#define for3(i,a,b)for(int i=(b);i>=a;i--)#define MEM1(a) memset(a,0,sizeof(a))#define MEM2(a) memset(a,-1,sizeof(a))#define MEM3(a) memset(a,0x3f,sizeof(a))#define MEMS(a) memset(a,'\0',sizeof(a))#define LL __int64const double PI = acos(-1.0);template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }template<class T> inline T Min(T a, T b) { return a < b ? a : b; }template<class T> inline T Max(T a, T b) { return a > b ? a : b; }using namespace std;template<class T>T Mint(T a, T b, T c) { if (a>b) { if (c>b) return b; return c; } if (c>a) return a; return c;}template<class T>T Maxt(T a, T b, T c) { if (a>b) { if (c>a) return c; return a; } else if (c > b) return c; return b;}const int maxn=200010;int T,n,m;int ans,f[maxn],sum[maxn];void Make_Set(int x){ f[x]=x; sum[x]=0;}int find(int x){ if(x!=f[x]){ int tmp=f[x]; f[x]=find(f[x]); sum[x]+=sum[tmp]; } return f[x];}void Union(int a,int b,int c){ int ra=find(a); int rb=find(b);if(ra==rb){if(sum[b]-sum[a]!=c)ans++;}else{f[rb]=ra;sum[rb]=sum[a]-sum[b]+c;}}int main(){#ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout);#endif while(~sfd(n,m)){ for2(i,0,n) Make_Set(i); int a,b,c; ans=0; while(m--){ sft(a,b,c); a--;//去掉这一行可以秒掉hdu 3047 Union(a,b,c); } pf(ans); } return 0;}
0 0
- hdu 3038(How Many Answers Are Wrong)+3047(Zjnu Stadium)(种类并查集)
- hdu 3038 How Many Answers Are Wrong (种类并查集)
- hdu3047 Zjnu Stadium && hdu 3038 How Many Answers Are Wrong
- HDU 3038 How Many Answers Are Wrong (并查集)(需复习!)
- HDU 3038 how many answers are wrong(带权并查集)
- HDU 3038 How Many Answers Are Wrong (带权并查集+区间判断)
- hdu 3038 How Many Answers Are Wrong(并查集)
- HDU - 3038 How Many Answers Are Wrong (带权并查集)
- HDU 3038 How Many Answers Are Wrong(带权并查集)
- HDU 3038 How Many Answers Are Wrong (并查集)
- HDU 3038 How Many Answers Are Wrong(带权并查集)
- HDU 3038 How Many Answers Are Wrong(并查集)
- hdu 3038 How Many Answers Are Wrong(并查集变种)
- HDU 3038 How Many Answers Are Wrong(带权并查集)
- hdu 3038 How Many Answers Are Wrong(带权并查集)
- How Many Answers Are Wrong hdu 3038 (带权并查集)
- hdu 3038 How Many Answers Are Wrong (带权并查集入门)
- HDU 3038 How Many Answers Are Wrong(维护节点间关系的并查集)
- 三种排序方法
- UIViewController的生命周期及iOS程序执行顺序
- Ubuntu-14 sshd 快速安装、配置、使用
- spring是什么
- OC中有关的内存泄露
- hdu 3038(How Many Answers Are Wrong)+3047(Zjnu Stadium)(种类并查集)
- POJ 2528 线段树离散化
- springMVC是什么
- OTG – Android USB Hos
- 使用Charles抓取ios http请求
- 将项目部署到linux步骤小记
- 动态规划问题的一般解决方案
- ORA-01938: 必须为 CREATE USER 指定 IDENTIFIED BY
- Struts框架配置Action和JSP的交互 如何在Action里面获取作用域