0x41 并查集
太菜了才做到并查集啊啊啊啊啊啊啊啊啊啊啊
还是很有收获的说
水
好题 poj1456 感受到并查集传递性的美妙啊!对于一个商品,去找他过期前那天的集合假如大于0相当于可以在这天卖出,然后这个集合和前一个集合合并!
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct node{int v,d;}a[11000]; bool cmp(node n1,node n2){return n1.v>n2.v;} int fa[11000]; int findfa(int x) { if(fa[x]==x)return x; fa[x]=findfa(fa[x]);return fa[x]; } int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%d%d",&a[i].v,&a[i].d); sort(a+1,a+n+1,cmp); for(int i=1;i<=10000;i++)fa[i]=i; int ans=0; for(int i=1;i<=n;i++) { if(findfa(a[i].d)!=0) { ans+=a[i].v; int fx=findfa(a[i].d); int fy=findfa(fx-1); fa[fx]=fy; } } printf("%d\n",ans); } return 0; }
NOI2002银河英雄传说 这个我没有系统的学“拓展域”和“边带权”,导致写的很挫。。用了奇技淫巧。。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; char ss[5]; int fa[31000],d[31000]; int findfa(int x) { if(fa[x]<0)return x; int dis=d[x]; int f=findfa(fa[x]); d[x]=dis+d[fa[x]];fa[x]=f; return fa[x]; } int main() { for(int i=1;i<=30000;i++)fa[i]=-i,d[i]=0; int Q,x,y; scanf("%d",&Q); while(Q--) { scanf("%s%d%d",ss+1,&x,&y); if(ss[1]=='M') { int fx=findfa(x),fy=findfa(y); int t=fa[fy]; fa[fy]=-fa[fx], d[fy]=1; fa[fx]=t; } else { int fx=findfa(x),fy=findfa(y); if(fx!=fy)printf("-1\n"); else printf("%d\n",max(d[x],d[y])-min(d[x],d[y])-1); } } return 0; }
正经的边带权,还是很秀的边带权
poj1182 食物链这题之前搞死人,正经的拓展域~
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int fa[310000]; int findfa(int x) { if(x==fa[x])return x; fa[x]=findfa(fa[x]);return fa[x]; } int main() { int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n*3;i++)fa[i]=i; int d,x,y,ans=0; for(int i=1;i<=k;i++) { scanf("%d%d%d",&d,&x,&y); if(x>n||y>n){ans++;continue;} int fx1=findfa(x),fy1=findfa(y); int fx2=findfa(x+n),fy2=findfa(y+n); int fx3=findfa(x+n*2),fy3=findfa(y+n*2); if(d==1) { if(fx1==fy2||fy1==fx2)ans++; else fa[fx1]=fy1, fa[fx2]=fy2, fa[fx3]=fy3; } else { if(fx1==fy1||fx1==fy2)ans++; else fa[fy1]=fx2, fa[fy2]=fx3, fa[fy3]=fx1; } } printf("%d\n",ans); return 0; }
感觉这个博客就是让我存代码的
pain and happy in the cruel world.