洛谷2212Watering the Fields S 最小生成树

题目链接:https://www.luogu.com.cn/problem/P2212

几乎是Kruskal裸题,但是建n*(n-1)条边给我T了俩点,后来我发现只要C(n,2)条边就可以,因为假设(vi,vj)和(vj,vi)之间有边,但是其中一条没用到则另外一条也用不到,因为他们一样长,如果其中一条边在生成树里面,另一条边也是不会用到的,因为不能有环。所以两点之间一条边就可以。这样时间就降了一半。另外,防T?快读?register?inline?orz orz

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef unsigned int ui;
  4 typedef long long ll;
  5 typedef unsigned long long ull;
  6 #define pf printf
  7 #define mem(a,b) memset(a,b,sizeof(a))
  8 #define prime1 1e9+7
  9 #define prime2 1e9+9
 10 #define pi 3.14159265
 11 #define lson l,mid,rt<<1
 12 #define rson mid+1,r,rt<<1|1
 13 #define scand(x) scanf("%llf",&x) 
 14 #define f(i,a,b) for(int i=a;i<=b;i++)
 15 #define scan(a) scanf("%d",&a)
 16 #define mp(a,b) make_pair((a),(b))
 17 #define P pair<int,int>
 18 #define dbg(args) cout<<#args<<":"<<args<<endl;
 19 #define inf 0x3f3f3f3f
 20 const int maxn=1e6+10;
 21 int n,m,t;
 22 inline int read(){
 23     int ans=0,w=1;
 24     char ch=getchar();
 25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
 26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
 27     return ans*w;
 28 }
 29 struct point{
 30     int x,y;
 31 }p[maxn];
 32 struct node{
 33     int u,v,w;
 34 }e[maxn*5];//注意边的数量,因为越界wa了一发 
 35 int cnt=0;
 36 int dis(int i,int j){return (p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y);}
 37 bool cmp(node& a,node& b)
 38 {
 39     return a.w<b.w;
 40 }
 41 int f[maxn];
 42 int ans,tot;
 43 void init()
 44 {
 45     f(i,1,n)f[i]=i;
 46     tot=0;
 47     ans=0;
 48 }
 49 int find(int x)
 50 {
 51     return x==f[x]?x:f[x]=find(f[x]);
 52 }
 53 void Union(int x,int y,int w)
 54 {
 55     int fx=find(x);
 56     int fy=find(y);
 57     if(fx==fy)return ;
 58     else 
 59     {
 60         if(w<m)return;
 61         if(tot==n-1)return ;
 62         f[fx]=fy;
 63         ans+=w;
 64         tot++;
 65     }
 66 }
 67 int main()
 68 {
 69     //freopen("input.txt","r",stdin);
 70     //freopen("output.txt","w",stdout);
 71     std::ios::sync_with_stdio(false);
 72     n=read(),m=read();
 73     init();
 74     f(i,1,n)
 75     {
 76         p[i].x=read(),p[i].y=read();
 77     }
 78     f(i,1,n)
 79         f(j,i+1,n)
 80         {
 81             if(i==j)continue;
 82             e[++cnt].u=i;
 83             e[cnt].v=j;
 84             e[cnt].w=dis(i,j);
 85         }
 86         sort(e+1,e+cnt+1,cmp);
 87         f(i,1,cnt)
 88         {
 89             if(e[i].w<m)continue;
 90             Union(e[i].u,e[i].v,e[i].w);
 91         }
 92         if(tot!=n-1)
 93         {
 94             pf("-1");
 95         }
 96         else 
 97         {
 98             pf("%d",ans);
 99         }
100  } 
原文地址:https://www.cnblogs.com/randy-lo/p/12567522.html