2020.6.25普及C组 灌溉农田(irrigation)【纪中】【最小生成树】

这道题需要用到最小生成树

我们首先将代价大于 C C C的管道标记好。
(没大于不用管,不参与最小生成树)
再跑一次最小生成树。

注意:
  1. 跑到一个点就要累计管道代价。
  2. 如果跑不完所有点就输出 − 1 -1 1
#include
#include
#include
#include
#include
#include
using namespace std;
int a[3010][3010],x[3010],y[3010],b[3010],c[3010];
int n,m,minn,k,ans;
int main()
{
    freopen("irrigation.in","r",stdin);
    freopen("irrigation.out","w",stdout);
    cin>>n>>m;
    for(int i=1; i<=n; i++)
     for(int j=1; j<=n; j++)
      a[i][j]=999999999;  //初始化最大值
    for(int i=1;i<=n;i++)
     {
        scanf("%d%d",&x[i],&y[i]);
        for(int j=1; j<=i-1; j++)   //求管道代价
         if((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])>=m)
          a[i][j]=a[j][i]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
     }
    b[1]=1;
    for(int i=2; i<=n; i++)
     c[i]=a[1][i];
    for(int j=1; j<=n-1; j++)  //最小生成树
     {
         minn=999999998;  //minn要赋值,不能赋999999999,因为初始化是999999999
         for(int j=1; j<=n; j++)
         if(b[j]==0&&c[j]<=minn)
          {
            minn=c[j];
            k=j;
          }
         b[k]=1;
         ans+=c[k];    //累计
         for(int j=1; j<=n; j++)
          if(b[j]==0&&a[j][k]<=c[j])
           c[j]=a[j][k];
     }
    for(int i=1; i<=n; i++)
     if(b[i]!=1)  //判断
      {
        cout<<-1;
        return 0;
      }
    cout<<ans;
    return 0;
}

你可能感兴趣的:(题解,图论)