Ink on paper 最小生成树-Prim-二分答案并查集
生活随笔
收集整理的這篇文章主要介紹了
Ink on paper 最小生成树-Prim-二分答案并查集
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意 :
- 平面直角坐標系中有n個水滴,每個水滴以0.5cm的速度擴散,求經(jīng)過多久所有的水滴可以連接在一起。
思路 :
- 將任意兩個墨水滴連接并求解最小生成樹就是墨水恰好全部連接時的情況。全部連接的時間就是最小生成樹中最長的邊形成的時間。求時間的平方,且 t2=s2t^2 = s^2t2=s2, 因此不用對距離開根號。O(n2n^2n2),1s,2 <= n <= 5000,n2=2.5e7n^2 = 2.5e7n2=2.5e7。
以下貼上二分答案并查集的ac代碼(來自隊友)
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 5050;int fa[maxn+10]; void init(int n){for(int i = 1; i <= n; i++)fa[i]=i;} int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} void merge(int x, int y){x=find(x);y=find(y);if(x!=y)fa[x]=y;} int count(int n){int cnt=0; for(int i = 1; i <= n; i++)if(fa[i]==i)cnt++;return cnt;}int n; struct node{LL x, y; }a[maxn]; LL d[maxn][maxn]; bool cmp(node x, node y){return x.x!=y.x ?x.x<y.x :x.y<y.y;} LL getd(node x, node y){return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y);} bool check(LL t){init(n);int cnt = 1;for(int i = 1; i <= n; i++){for(int j = i+1; j <= n; j++){if(t>=d[i][j]){if(find(i)!=find(j)){cnt++;if(cnt==n)break;merge(i,j);}}}if(cnt==n)break;}return cnt==n; }int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T; cin>>T;while(T--){cin>>n; for(int i = 1; i <= n; i++)cin>>a[i].x>>a[i].y;for(int i = 1; i <= n; i++)for(int j = i+1; j <= n; j++)d[i][j] = getd(a[i],a[j]);//sort(a+1,a+n+1,cmp);LL l = 0, r = 1e15+10;while(l < r){LL mid = (l+r)/2;if(check(mid)){r = mid;}else {l = mid+1;}}cout<<r<<"\n";}return 0; }總結
以上是生活随笔為你收集整理的Ink on paper 最小生成树-Prim-二分答案并查集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GCD Game 博弈论-Nim-质因数
- 下一篇: Singing Superstar 字符