zoukankan      html  css  js  c++  java
  • [USACO14MAR]浇地Watering the Fields

    题目传送门

    这题可以用最小生成树来写,一道Kruskal裸题 虽然我TLE了很多遍,(数组开大了)

    Kruskal简单易懂,代码清爽 时间复杂度(O(mlogm))

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,m;
    int f[2010],x[2010],y[2010];//f为father,x,y为坐标 
    struct node{
    	int x,y,len;
    }a[10000000];//数组要开大点 
    bool cmp(node x,node y){return x.len<y.len;}//边权值从小到大排序 
    inline int ojld(int x1,int x2,int y1,int y2){return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);}//计算欧几里得距离 
    int find(int x){
    	while(x!=f[x])x=f[x]=f[f[x]];
    	return x;
    }//找祖先 
    int sum;
    void kruskal(){//Kruskal模板 
    	int t=0,ans=0;
    	sort(a+1,a+sum+1,cmp);//排序 
    	for(int i=1;i<=n;i++)f[i]=i;//初始化,把father定义为自己 
    	for(int i=1;i<=sum;i++){
    		int faa=find(a[i].x);
    		int fbb=find(a[i].y);
    		if(faa!=fbb){//如果祖先不一样 
    		    f[faa]=fbb; 
    			ans+=a[i].len;//加上边权值 
    		    t++;
    		}
    		if(t==n-1)break;//如果与n-1条边相等,退出循环 
    	}
    	if(t==n-1)printf("%d",ans);
    	else puts("-1");//记得特判~ 
    }
    int main(){
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d %d",&x[i],&y[i]);
        for(int i=1;i<=n;i++)
         for(int j=i+1;j<=n;j++){
         	int d=ojld(x[i],x[j],y[i],y[j]);
         	if(d>=m)
         	 sum++,a[sum].x=i,a[sum].y=j,a[sum].len=d;//如果两个农田距离大于m,存起来 
    	 }
        kruskal();
        return 0;
    }
    
    

    完结撒花!

  • 相关阅读:
    上台阶
    格子游戏
    找同乡
    约德尔测试
    hihocoder_week195奖券兑换
    hihocoder_week197逆序单词
    牛客网--数串
    hihocoder_offer收割编程练习赛55_3
    hihocoder_offer收割编程练习赛55_2
    hihocoder_offer收割编程练习赛55_1
  • 原文地址:https://www.cnblogs.com/qzwer/p/12940253.html
Copyright © 2011-2022 走看看