您的位置:首页 > 其它

POJ 2075 Tangled in Cables 最小生成树 Kruskal && Prim

2015-08-13 18:57 531 查看
Tangled in Cables

Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 6200 Accepted: 2441
Description

You are the owner of SmallCableCo and have purchased the franchise rights for a small town. Unfortunately, you lack enough funds to start your business properly and are relying on parts you have found in an old warehouse you bought. Among your finds is a single
spool of cable and a lot of connectors. You want to figure out whether you have enough cable to connect every house in town. You have a map of town with the distances for all the paths you may use to run your cable between the houses. You want to calculate
the shortest length of cable you must have to connect all of the houses together.
Input

Only one town will be given in an input. 
The first line gives the length of cable on the spool as a real number. 

The second line contains the number of houses, N 

The next N lines give the name of each house's owner. Each name consists of up to 20 characters {a–z,A–Z,0–9} and contains no whitespace or punctuation. 

Next line: M, number of paths between houses 

next M lines in the form

< house name A > < house name B > < distance > 

Where the two house names match two different names in the list above and the distance is a positive real number. There will not be two paths between the same pair of houses.
Output

The output will consist of a single line. If there is not enough cable to connect all of the houses in the town, output 

Not enough cable 

If there is enough cable, then output 

Need < X > miles of cable 

Print X to the nearest tenth of a mile (0.1).
Sample Input
100.0
4
Jones
Smiths
Howards
Wangs
5
Jones Smiths 2.0
Jones Howards 4.2
Jones Wangs 6.7
Howards Wangs 4.0
Smiths Wangs 10.0

Sample Output
Need 10.2 miles of cable

注-此题为:POJ  2075  Tangled in Cables

题意:       现在一个小镇要通过电缆来通电.给你小镇的房屋数目N和对应的名称,已经它们之间的距离.问你最少需要多少长的电缆才能让小镇所有房屋都通上点.

已知总电线的长度,判断是否够,够则输出 所用最小值,不够则输出 Not enough cable

       最小生成树  ,  Kruskal && Prim  ,将房屋转变为编号,就是一  模板题  (hdoj s输出控制精度时要   用  f  不能用   lf  )

已AC代码:(Kruskal)

#include<cstdio>
#include<cstring>
#define M 25000
#include<algorithm>
using namespace std;

int per[300];   // 并查集
double x[300],y[300];
int n,m;
char name[10000][50];

struct node{
int u,v;
double w;   //w为距离
}s[M];

bool cmp(node a,node b)
{
return a.w<b.w;
}

void into()     //初始化
{
for(int i=0;i<=n;++i)
per[i]=i;
}

int find(int x)    // 查找根节点
{
return x == per[x] ? x : per[x] = find(per[x]);
}

bool join(int a,int b)    //合并根节点,并判断是否成环
{
int fa=find(a);
int fb=find(b);
if(fa!=fb)
{
per[fa]=fb;
return true;
}
return false;
}

int main()
{
double sl,d;
int i,j;
char ch1[50],ch2[50];
while(scanf("%lf",&sl)!=EOF)  //end of file
{
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%s",name[i]);
scanf("%d",&m);

for(i=0;i<m;++i)   //读入数据
{
scanf("%s%s%lf",ch1,ch2,&d);

for(j=1;j<=n;++j)  // 将 name 变为编号
{
if(strcmp(ch1,name[j])==0)
s[i].u=j;
if(strcmp(ch2,name[j])==0)
s[i].v=j;
s[i].w=d;
}
}

into();   //初始化根节点
sort(s,s+m,cmp);    //按距离从小到大排序

double sum=0;
for(i=0;i<m;++i)
{
if(join(s[i].u,s[i].v))
{
sum+=s[i].w;
}
}
if(sl>=sum)
printf("Need %.1lf miles of cable\n",sum);
else
printf("Not enough cable\n");
}
return 0;
}


已AC代码:(Prim)

#include<cstdio>
#include<cstring>
#define INF 0xfffffff

double sum;  //最小生成树权值和
int n,m;
int vis[300];    //map二维数组存图,low记录每2个点间最小权值,vis标记某点是否已访问
double map[300][300],low[300];
char name[10000][50];

void prim()
{
memset(vis,0,sizeof(vis));
int i,j,pos,t;
double MIN;

for(i=1;i<=n;++i)  	//从某点开始,分别标记vis和记录该点pos
low[i]=map[1][i];  	//第一次给low数组赋值 map的第一行
vis[1]=1;pos=1;t=0;

for(i=1;i<n;++i)   //再运行n-1次,一次找一个最小
{
MIN=INF;
for(j=1;j<=n;++j)
{
if(vis[j]==0&&low[j]<MIN)
{
MIN=low[j];  // 找出最小值min,记录位置pos
pos=j;
}
}
sum+=MIN;
vis[pos]=1;   //标记该点已访问
for(j=1;j<=n;++j)    //更新权值low 把 map的 pos 行中比对应的 low 小的赋给low
if(vis[j]==0&&low[j]>map[pos][j])
low[j]=map[pos][j];
}
}

int main()
{
double sl,d;
int i,j,a,b;
char ch1[50],ch2[50];
while(scanf("%lf",&sl)!=EOF)  //end of file
{
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%s",name[i]);
scanf("%d",&m);

for(i=1;i<=n;++i)  //初始化为无穷大,没有相连的 不再考虑
for(j=1;j<=n;++j)
map[i][j]=INF;

for(i=0;i<m;++i)   //读入数据
{
scanf("%s%s%lf",ch1,ch2,&d);

for(j=1;j<=n;++j)  //编号
{
if(strcmp(ch1,name[j])==0)
a=j;
if(strcmp(ch2,name[j])==0)
b=j;
}
map[a][b]=map[b][a]=d;
}

sum=0;
prim();

if(sl>=sum)
printf("Need %.1lf miles of cable\n",sum);
else
printf("Not enough cable\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息