ZLGG found a magic theory that the bigger banana the bigger banana peel .This important theory can help him make a portal in our universal. Unfortunately, making a pair of portals will cost min{T} energies. T in a path between point V and point U is the length of the longest edge in the path. There may be lots of paths between two points. Now ZLGG owned L energies and he want to know how many kind of path he could make.
Input
There are multiple test cases. The first line of input contains three integer N, M and Q (1 < N ≤ 10,000, 0 < M ≤ 50,000, 0 < Q ≤ 10,000). N is the number of points, M is the number of edges and Q is the number of queries. Each of the next M lines contains three integers a, b, and c (1 ≤ a, b ≤ N, 0 ≤ c ≤ 10^8) describing an edge connecting the point a and b with cost c. Each of the following Q lines contain a single integer L (0 ≤ L ≤ 10^8).
Output
Output the answer to each query on a separate line.
Sample Input
10 10 10 7 2 1 6 8 3 4 5 8 5 8 2 2 8 9 6 4 5 2 1 5 8 10 5 7 3 7 7 8 8 10 6 1 5 9 1 8 2 7 6
Sample Output
36 13 1 13 36 1 36 2 16 13
先说题目意思吧 真TM想踹题白白浪费一小时就搜各个博客就为了想知道题目是啥意思 好吧 它真的是一道好题
给出n,m,q; n是有多少个点 m是有多少遍 q是有多少询问
在给出当前的能量的情况下!
就是求A集合 和 B集合之间 他们之间相互连接!相互连接起来可以有多少个点对(X,Y)是小于当前的能量
先把边从小到大排个序,怎么那么像最小生成树。。。。。啊啊啊啊 其实就是就有点像变形最小生成树
离线离线就是输入完在处理,咋们平时不都是边输入边merge吗因为没有权值啊 这题有啊
举个栗子
排完序对吧 1 1 2 5 6 6 7 8 9 10
排完序
7 2 1
5 8 2
6 8 3
6 4 5
2 1 5
8 10 5
7 3 7
4 5 8
7 8 8
2 8 9
因为m条边啊所以肯定不能大于它呢 他们连接花费的东西当然也不能大于当前的能量啊
看下这个地方
当前值为1 时候 2和7一堆了 此刻点对有1
当前值为1 。。。。。。。没改变
当前值为2 又增加了一个点对了 58 此刻点对有2 扎堆的有 (27) (58)
当前值为5!!
6 8== 3对吧 可是此刻 5和8在一起了 6再进去就是加2 对吧 所以 现在加2 点对为 1 + 1 + 2 =4
现在一堆的有 27 856
6 4 ==5 进去了 所以!此刻 4 和568扎堆了 那么点对再加3 点对为1+1+2+3=7
现在一堆的有 27 4856
2 1 ==== 5 进去了 所以!1和27扎堆了 那么点对再加2 点对为1 + 1 + 2 + 3 + 2 = 9
现在一堆的有 127 4856
8 10 ====5 进去了 所以! 10 和4856扎堆了 那么点对为1 + 1 + 2 + 3 + 2 + 4 = 13
现在你懂什么意思了把? 别管这句话真的
T in a path between point V and point U is the length of the longest edge in the path 害老子想了一晚上生气
a 集合和b集合联合在一起 sum = rank[a] * rank[b] 你想想 27 34 他们点对是不是 1 + 1 + 4 对吧 rank[a] = 2;
rank[b] = 2; 是吧? 所以就是4 over! 再见!
代码!
#include<cstdio>
#include<algorithm>
using namespace std;
int n, m, q;
const int maxn = 1e4+10;
int pre[maxn],ranks[maxn];
struct node
{
int x , y , val;
bool operator < (const node &a)const{
return val < a.val;
}
}edge[maxn * 5];
struct GG
{
int id,q,ans;
}query[maxn];
bool cmp1(GG a, GG b){
return a.q < b.q;
}
bool cmp2(GG a, GG b){
return a.id < b.id;
}
int find(int x)
{
if(pre[x] == x)
return x;
else
return pre[x] = find(pre[x]);
}
int merge(int x,int y)
{
int fx = find(x);
int fy = find(y);
if(fx != fy)
{
pre[fy] = fx;
int temp = ranks[fx];
ranks[fx] = ranks[fx] + ranks[fy];
return temp * ranks[fy];
}
return 0;
}
int main()
{
while(~scanf("%d %d %d",&n,&m,&q))
{
for(int i = 1 ; i <= m; i++)
scanf("%d %d %d",&edge[i].x, &edge[i].y, &edge[i].val);
for(int i = 1; i <= q; i++)
{
scanf("%d",&query[i].q);
query[i].id = i;
query[i].ans = 0;
}
sort(edge + 1, edge + 1 + m);
sort(query + 1,query + 1 + q, cmp1);
for(int i = 1; i <= m; i ++)
printf("%d %d %d \n",edge[i].x ,edge[i].y, edge[i].val);
for(int i = 1; i <= n; i++)
{
pre[i] = i;
ranks[i] = 1;
}
int cnt = 1;
for(int i = 1; i <= q; i ++)
{
query[i].ans += query[i - 1].ans;
while(cnt <= m && edge[cnt].val <= query[i].q) //因为m条边啊所以肯定不能大于它呢 他们连接花费的东西当然也不能大于当前的能量啊
{
query[i].ans += merge(edge[cnt].x, edge[cnt].y);
cnt++;
}
}
sort(query + 1,query + 1 + q, cmp2);
for(int i = 1; i <= q; i ++)
printf("%d\n",query[i].ans);
}
return 0;
}