HDU 1863 畅通工程

终于把杭电的畅通系列做光了,图论的算法总算是初步有点入门了

这道题也不难,但是主要数组要开大点就可以。先用并查判断连通性,然后用prim就可以搞定了

 

Title

 

#include <iostream>
using namespace std;
#define inf 1000000
int set[1001],Dis[1001][1001],sum;
struct Edge
{
 int point;
 int lowcost;
}edge[1001];
int find(int x)
{
 int i,j,r = x;
 while (set[r] != r)
 {
  r = set[r];
 }
 i = x;
 while (i != r)
 {
  j = set[i];
  set[i] = r;
  i = j;
 }
 return r;
}
void merge(int a,int b)
{
 int x = find(a);
 int y = find(b);
 if (x != y)
  set[x] = y;
}

int main()
{
 int n,m,i,j,k,a,b,x,r;
 while (scanf("%d %d",&n,&m) == 2  && n != 0)
 {
  for (i = 0;i <= m;i++)
  {
   set[i] = i;
   for (j = 0;j <= m;j++)
    Dis[i][j] = inf;
  }
  for (i = 1;i <= n;i++)
  {
   scanf("%d %d %d",&a,&b,&x);
   merge(a,b);
   if (x < Dis[a][b])
    Dis[a][b] = Dis[b][a] = x;
  }
  r = 0;
  for (i = 1;i <= m;i++)
   if (set[i] == i)
    r++;
   sum = 0;
   if (r == 1)
   {
    k = 0;
    int min;
    j = 1;
    for (i = 1;i <= m;i++)
    {
     edge[i].point = i;
     edge[i].lowcost = Dis[j][i];
    }
    edge[j].lowcost = 0;
    for (i = 1;i <= m;i++)
    {
     min = inf;
     for (j = 1;j <= m;j++)
     {
      if (edge[j].lowcost != 0 && edge[j].lowcost < min)
      {
       k = j;
       min = edge[j].lowcost;
      }
     }
     sum += edge[k].lowcost;
     edge[k].lowcost = 0;
     for (j = 1;j <= m;j++)
     {
      if (Dis[k][j] < edge[j].lowcost)
      {
       edge[j].point = k;
       edge[j].lowcost = Dis[k][j];
      }
     }
    }
    printf("%d\n",sum);
   }
   else
    printf("?\n");
   
 }  
 return 0;
}

 

 

 

posted @ 2008-09-08 21:13  cnnbboy  阅读(343)  评论(0)    收藏  举报