九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11877843
离线并查集
HDU 3938:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <queue>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <set>
#include <vector>
#define inf 107374182
#define ll int
using namespace std;
inline ll Max(ll a,ll b){return a>b?a:b;}
inline ll Min(ll a,ll b){return a<b?a:b;}
int n,m;
struct Edge{
int u,v,d;
}edge[50500];
int edgenum,maxedgenum;
struct que{
int l,ans,num;
}query[10005];
bool cmp1(Edge a,Edge b){return a.d<b.d;}
bool cmp2(que a,que b){return a.num<b.num;}
bool cmp3(que a,que b){return a.l<b.l;}
int f[N],sum[N];
int find(int x){
if(x==f[x])return x;
return f[x]=find(f[x]);
}
int Union(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy)return 0;
maxedgenum++;
int temp; if(f[fx]>f[fy])temp=fx,fx=fy,fy=temp;
f[fy]=fx;
temp=sum[fx]*sum[fy];
sum[fx]+=sum[fy];
return temp;
}
void init(){
edgenum=0;
maxedgenum=0;
for(int i=0;i<=n;i++)sum[i]=1,f[i]=i;
}
int main()
{
int i,j,q;
while(~scanf("%d%d%d",&n,&m,&q)){
for(i=0;i<m;i++)scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].d);
for(i=0;i<q;i++)
{scanf("%d",&query[i].l); query[i].ans=0; query[i].num=i;}
sort(edge,edge+m,cmp1);
init();
sort(query,query+q,cmp3);
for(i=0;i<q;i++){
while(edge[edgenum].d<=query[i].l && maxedgenum<n && edgenum<m)
{
int fa=find(edge[edgenum].u),fb=find(edge[edgenum].v);
edgenum++;
if(fa==fb)continue;
query[i].ans+=Union(fa,fb);
}
if(i>0)query[i].ans+=query[i-1].ans;
}
sort(query,query+q,cmp2);
for(i=0;i<q;i++)printf("%d\n",query[i].ans);
}
return 0;
}
HDU 4750:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
#define zero(x) (((x)>0?(x):-(x))<eps)
#define PI acos(-1.0)
#define Max 600009
#define inf 0x7fffffff
struct data{
int u, v, len;
}e[Max];
int n, m, pa[Max],in[Max], x[Max], mp[Max], nu[Max];
bool vis[Max];
bool cmp(data a, data b){
if(a.len < b.len) return true;
return false;
}
void make_set(){
for(int x = 0; x < n; x ++) {
pa[x] = x;
nu[x] = 1;
}
}
int find_set(int x){
if(x != pa[x])
pa[x] = find_set(pa[x]);
return pa[x];
}
void kruskal(){
memset(vis,0,sizeof(vis));
int i, ans = 0 , have = 0;
make_set();
int pre = 0;
for(i = 0; i < m; i ++){
int now = e[i].len;
int x = find_set(e[i].v);
int y = find_set(e[i].u);
if(x != y){
mp[now] = nu[x] * nu[y] * 2;
nu[x] += nu[y];
pa[y] = x;
}
}
return;
}
int main(){
int t, i, j, val;
while(scanf("%d%d",&n,&m) != EOF) {
memset(mp, 0, sizeof(mp));
for(int i = 0; i < m; i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].len);
int p;
scanf("%d",&p);
for (int i = 0; i < p; ++i) {
scanf("%d",&x[i]);
e[m + i].len = x[i];
e[m + i].u = -1;
e[m + i].v = i;
}
sort(e, e + m + p, cmp);
int tp = e[0].len;
e[0].len = 1;
if (e[0].u == -1)
x[e[0].v] = 1;
for (int i = 1; i < m + p; ++i) {
if (e[i].len == tp)
e[i].len = e[i - 1].len;
else {
tp = e[i].len;
e[i].len = e[i - 1].len + 1;
}
if (e[i].u == -1)
x[e[i].v] = e[i].len;
}
tp = e[m + p - 1].len;
for (int i = 0; i < m + p; ++i)
if (e[i].u == -1)
e[i].len = tp + 1;
sort(e, e + m + p, cmp);
kruskal();
for (int i = 1; i <= tp; ++i)
mp[i] += mp[i - 1];
for (int i = 0; i < p; ++i)
printf("%d\n", mp[tp] - mp[x[i] - 1]);
}
return 0;
}