Pku 2832 How Many Pairs?

9 篇文章 0 订阅
4 篇文章 0 订阅

题目:

 How Many Pairs?

来源:

 Pku 2832

题目大意:

 题意让我理解了半天,果然英语不好。

 其实就是n个点m条边q次访问,每次输出任何一对点只要其所经过的边的最长边比  访问值小就行的有效点数量

数据范围:

 1 < N ≤ 10,000, 0 < M ≤ 50,000, 0 < Q ≤ 10,000

样例:

 4 5 4
 1 2 1
 2 3 2
 2 3 5
 3 4 3
 4 1 4
 0
 1
 3
 2
0
1
6
3
 

做题思路:

 如果题意看懂了貌似就不那么难了,写的是类似kruskal的,所以就那么叫了。先把  访问值和边按从小到大排了,然后并查集合并,合并时注意减去重复的

知识点:

 并查集、kruskal

type
 act=record
 x,y,d:longint;
 end;
 atp=array[0..50000]of longint;
var
 a:array[0..50010]of act;
 ans,time,tot,b,f:array[0..50000]of longint;
 n,i,q,m,x,y,d:longint;
procedure qsorta(l,r:longint);
var
 i,j,k:longint;
 t:act;
begin
 i:=l;j:=r;
 k:=a[(l+r)shr 1].d;
 repeat
  whilea[i].d<k do inc(i);
  whilea[j].d>k do dec(j);
  ifi<=j then
  begin
   t:=a[i];a[i]:=a[j];a[j]:=t;
   inc(i);dec(j);
   end;
 untili>j;
 ifi<r then qsorta(i,r);
 ifj>l then qsorta(l,j);
end;
procedure qsortb(l,r:longint;vart:atp);{<t数组是形变参。。。>}
var
 tmp,i,j,k:longint;
begin
 i:=l;j:=r;
 k:=t[(l+r)shr 1];
 repeat
  whilet[i]<k do inc(i);
  whilet[j]>k do dec(j);
  ifi<=j then
  begin
   tmp:=t[i];t[i]:=t[j];t[j]:=tmp;
   tmp:=time[i];time[i]:=time[j];time[j]:=tmp;
   inc(i);dec(j);
   end;
 untili>j;
 ifi<r then qsortb(i,r,t);
 ifj>l then qsortb(l,j,t);
end;
function getf(x:longint):longint;
begin
 iff[x]=x then exit(x);
 f[x]:=getf(f[x]);
 exit(f[x]);
end;
procedure union(x,y:longint);
begin
 f[x]:=y;
end;
procedure kruskal;{<好像kruskal所以就这么命名啦>}
var
 i,j,last,x,y:longint;
begin
 fori:=1 to n do
  begin
  f[i]:=i;
  tot[i]:=1;{<初始化对应点>}
  end;
 fillchar(ans,sizeof(ans),0);
 last:=1;
 fori:=1 to q do
  begin
  ans[time[i]]:=ans[time[i-1]];{<访问值再time下是越来越大的,所以可以先把之前求出来的赋给要求的>}
   forj:=last to m do
   begin
     ifa[j].d>b[i] then{<由于对边排序了,所以第一个大于访问值的就是第一个大于的>}
     begin
      last:=j;
      break;
     end;
  x:=getf(a[j].x);y:=getf(a[j].y);
   ifx<>y then
   begin
    union(x,y);
    ans[time[i]]:=ans[time[i]]-tot[x]*(tot[x]-1) div 2-tot[y]*(tot[y]-1) div2;{<累计答案是要注意不要让对应点重复了,所以先减后加>}
    tot[y]:=tot[x]+tot[y];
    ans[time[i]]:=ans[time[i]]+tot[y]*(tot[y]-1)div 2;
   end;
  end;
 end;
end;
begin
 readln(n,m,q);
 fori:=1 to m do
  begin
   witha[i] do{<记录性特有滴。。>}
  readln(x,y,d);
  end;
 fori:=1 to q do
  begin
  time[i]:=i;{<排序就不动原数了,以免输出时麻烦,所以把序号排了>}
  readln(b[i]);
  end;
 qsorta(1,m);
 qsortb(1,q,b);
 kruskal;
 fori:=1 to q do writeln(ans[i]);
end.
题目来源: http://poj.org/problem?id=2832

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值