JOJ 1170: Wire Is So Expensive

最小生成树。


StatusIn/OutTIME LimitMEMORY LimitSubmit TimesSolved UsersJUDGE TYPE
stdin/stdout3s8192K551233Standard

1st Jilin University ACM International Collegiate Programming Contest

Assume you are working for ACM(Andrew Communication Management) company. This company is specialized to make towns connected by wire. We all know that wire can only be put along roads. But in recent years, the price of per metre of wire is going higher and higher. So the company needs to know what is the minimal length of wire they have to prepare to connect several towns together in order that each town can connect to another by wire. You are given a map of N towns and how they are connected by roads. Your task is to write a program to determine the minimal length of wire.

Input Specification

This problem contains M maps. The first line of input is an integer M. Then follow M maps' descriptions, each of which is described below:

N
a1 b1 c1
a2 b2 c2
...
an bn cn
0 0 0

where N(1<=N<=20) is the number of towns(1, 2, ... N) and ai, bi, ci means there is a road between towns ai and bi(1<=ai, bi<=N) with length ci(1<=ci<=100). Three 0s mark the end of a map. All the numbers will be integers.

Output Specification

For each map, you should print a line containing the minimal length of wire the company has to prepare.

Sample Input

1
5
1 2 3
1 4 5
2 3 6
2 4 2
2 5 6
3 5 5
4 5 8
0 0 0

Sample Output

16

 


Submit / Problem List / Status / Discuss

prim算法:

#include <iostream>
#include <string>
#define Inf 100000
using namespace std;
int ans[110][110];
int s[110];
int lowcost[110];
int prim(int n)
{
    int i,j,k,mincost ,min;
    s[1] = 1;
    mincost = 0;
    for(i = 2 ;i<=n;i++)
        lowcost[i] = ans[1][i];
    for(i = 1;i<n;i++)
    {
        min = Inf;
        j = 1;
        for(k=2;k<=n;k++)
        {
            if(!s[k] && lowcost[k]<min)
            {
                min = lowcost[k];
                j = k;
            }
        }
        mincost += min;
        s[j] = 1;
        for(k=2;k<=n;k++)
        {
            if(!s[k] && ans[j][k] < lowcost[k])
                lowcost[k] = ans[j][k];
        }
    }
    return mincost ;
}
int main()
{
    int cas;
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%d",&cas);
        while(cas--)
        {
            int n;
            while(scanf("%d",&n)!=EOF)
            {
                int a,b,val;
                for(int i=1;i<=n;i++)
                    for(int j=1;j<=n;j++)
                        ans[i][j] = Inf;
                memset(s,0,sizeof(s));
                while(scanf("%d%d%d",&a,&b,&val))
                {
                    if(a == 0 && b == 0 && val == 0)
                    break;
                    ans[a][b] = val;
                    ans[b][a] = val;
                }
                cout<<prim(n)<<endl;
            }
        }
    return 0;
}

 

还有错误的KRUSKAL算法,明天还得研究:

#include<iostream>
#include<algorithm>
using namespace std;

struct t
{
 int x;
 int y;
 int l;
}d[200],d2[200];
int m,n;

bool cmp(struct t a,struct t b)
{
 return a.l<=b.l;
}

int main()
{
 int i,j,temp,a,b,c,num;
 freopen("in.txt","r",stdin);
 freopen("out.txt","w",stdout);
    scanf("%d",&m);
    while(m--)
 {
  scanf("%d",&n);
  i=0;
  scanf("%d%d%d",&a,&b,&c);
  while(a!=0&&b!=0&&c!=0)
  {
   d[i].x=a;
   d[i].y=b;
   d[i].l=c;
   scanf("%d%d%d",&a,&b,&c);
   i++;
  }
  sort(d,d+i,cmp);
  num=0;
  temp=0;
  while(num<n-1)
  {
   bool falt1=true,falt2=true;
   for(j=0;j<num;j++)
   {
      if(d2[j].y==d[temp].y)  falt1=false;
      if(d2[j].x==d[temp].x)  falt2=false;
   }
      if(falt1||falt2) 
        {
    d2[num].x=d[temp].x;
    d2[num].y=d[temp].y;
    d2[num].l=d[temp].l;
    num++;
     }
   temp++;
  }
  int sum=0;
  for(i=0;i<num;i++)
       sum+=d2[i].l;
  printf("%d/n",sum);
  }
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值