hdu 3047(带权并查集)
2017-10-13 09:08
267 查看
传送门
昨天才考过一道差不多的,用离线+BFS预处理+裸并查集水掉了(^_^)
题意:
有n个人坐在zjnu体育馆里面,然后给出m个他们之间的距离, 代表B的座位比A多X.。然后求出这m个关系之间有多少个与之前的关系有冲突。
题解:
用带权并查集维护点到根距离,在merge操作时:
inline void merge(int x,int y,int fx,int fy,int d) {
fa[fy]=fx;
dis[fy]=dis[x]+d-dis[y];
}
P.S.注意每组数据初始化时dis也要清空!!!
昨天才考过一道差不多的,用离线+BFS预处理+裸并查集水掉了(^_^)
题意:
有n个人坐在zjnu体育馆里面,然后给出m个他们之间的距离, 代表B的座位比A多X.。然后求出这m个关系之间有多少个与之前的关系有冲突。
题解:
用带权并查集维护点到根距离,在merge操作时:
inline void merge(int x,int y,int fx,int fy,int d) {
fa[fy]=fx;
dis[fy]=dis[x]+d-dis[y];
}
P.S.注意每组数据初始化时dis也要清空!!!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN=5e4+4; int n,m; int fa[MAXN],dis[MAXN]; inline int read() { int x=0;char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x; } int find(int x) { if (x==fa[x]) return x; int t=fa[x]; fa[x]=find(fa[x]); dis[x]+=dis[t]; return fa[x]; } inline void merge(int x,int y,int fx,int fy,int d) { fa[fy]=fx; dis[fy]=dis[x]+d-dis[y]; } int main() { // freopen("hdu 3047.in","r",stdin); while (~scanf("%d%d",&n,&m)) { int cfc=0; for (register int i=1;i<=n;++i) fa[i]=i,dis[i]=0; for (register int i=0;i<m;++i) { int x=read(),y=read(),d=read(); int fx=find(x),fy=find(y); if (fx==fy) { if (dis[y]-dis[x]!=d) ++cfc; } else merge(x,y,fx,fy,d); } printf("%d\n",cfc); } return 0; }
相关文章推荐
- HDU 3047 Zjnu Stadium(带权并查集)
- Zjnu Stadium(hdu-3047)(带权并查集)
- HDU 3047 带权并查集
- hdu 3047 Zjnu Stadium(带权并查集)
- HDU 3047 Zjnu Stadium 带权并查集
- HDU 3047 Zjnu Stadium(带权并查集,路径压缩)
- HDU 3047 Zjnu Stadium(带权并查集)
- HDU 3047 并查集
- hdu 3047 Zjnu Stadium 带权并查集
- HDU 3047 Zjnu Stadium - 并查集
- hdu 3047 Zjnu Stadium 带权并查集
- hdu 3047 带权并查集
- hdu 3047 带权并查集
- hdu 3047 Zjnu Stadium (带权并查集)
- hdu 3047 带权并查集
- HDU 3047 Zjnu Stadium 带权并查集
- HDU 3047 Zjnu Stadium 带权并查集
- hdu 3038(How Many Answers Are Wrong)+3047(Zjnu Stadium)(种类并查集)
- HDU 3047 Zjnu Stadium 带权并查集
- hdu 3047(带权并查集)