HDU - 3938(Portal)並查集+離線
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;
}