HOJ Tangled in Cables 图论 最小生成树 prim
2012-02-29 22:11
465 查看
Tangled in Cables
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
Several data sets will be given in an input file.
The first line of each data set 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.
Input is terminated by End-of-File.
Output
For each data set in the input, output 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
题目:
问他能不能用现有的钱连接所有的人
分析:
最小生成树算法,prim算法实现,见代码分析:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define X 1005
#define INF 0x7f //最大值
string name[X],ch1,ch2;//储存之前输入的名字,后面输入的有连接关系两个人
double map[X][X],dis[X];//储存有连接关系的两人的值,计算距离
bool use[X]; //标记用过没
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
double total,cur;
int n,m;
while(scanf("%lf",&total)!=EOF)
{
memset(map,INF,sizeof(map));//全置为无穷大
scanf("%d",&n);
for(int i=0;i<n;i++)//输入所有人的名字
cin>>name[i];
scanf("%d",&m);
for(int i=0;i<m;i++)
{
bool flag1 = false,flag2 = false;
int x,y;
cin>>ch1>>ch2;
scanf("%lf",&cur);
for(int j=0;j<n&&(!flag1||(!flag2));j++)
{
if(!flag1&&name[j]==ch1)//如果还没找到,并且当前字符串等于之前某个人的名字
{ //根据&&符号短路的关系,先判之前有没有找到,已找到的话就不用继续比较了
x = j; //记录之前输入的名字的序号
flag1 = true;
}
if(!flag2&&name[j]==ch2)//同理
{
y = j;
flag2 = true;
}
}
map[x][y] = map[y][x] = cur;//记录到关系地图中
}
///////////////////标准prim算法模板
memset(dis,INF,sizeof(dis));//置为无穷大
memset(use,false,sizeof(use));//标记未使用过
int k;
for(int i=0;i<n;i++)
dis[i] = map[0][i];
use[0] = true;
double ans = 0,MIN;
for(int i=0;i<n-1;i++)
{
MIN = INF;
for(int j=1;j<n;j++)
if(!use[j]&&MIN>dis[j])
MIN = dis[k=j];
ans+=dis[k];
use[k] = true;
for(int j=1;j<n;j++)
if(!use[j])
dis[j] = min(dis[j],map[k][j]);
}
if(ans<=total)
printf("Need %.1lf miles of cable\n",ans);
else
printf("Not enough cable\n");
}
return 0;
}
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
Several data sets will be given in an input file.
The first line of each data set 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.
Input is terminated by End-of-File.
Output
For each data set in the input, output 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
题目:
问他能不能用现有的钱连接所有的人
分析:
最小生成树算法,prim算法实现,见代码分析:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define X 1005
#define INF 0x7f //最大值
string name[X],ch1,ch2;//储存之前输入的名字,后面输入的有连接关系两个人
double map[X][X],dis[X];//储存有连接关系的两人的值,计算距离
bool use[X]; //标记用过没
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
double total,cur;
int n,m;
while(scanf("%lf",&total)!=EOF)
{
memset(map,INF,sizeof(map));//全置为无穷大
scanf("%d",&n);
for(int i=0;i<n;i++)//输入所有人的名字
cin>>name[i];
scanf("%d",&m);
for(int i=0;i<m;i++)
{
bool flag1 = false,flag2 = false;
int x,y;
cin>>ch1>>ch2;
scanf("%lf",&cur);
for(int j=0;j<n&&(!flag1||(!flag2));j++)
{
if(!flag1&&name[j]==ch1)//如果还没找到,并且当前字符串等于之前某个人的名字
{ //根据&&符号短路的关系,先判之前有没有找到,已找到的话就不用继续比较了
x = j; //记录之前输入的名字的序号
flag1 = true;
}
if(!flag2&&name[j]==ch2)//同理
{
y = j;
flag2 = true;
}
}
map[x][y] = map[y][x] = cur;//记录到关系地图中
}
///////////////////标准prim算法模板
memset(dis,INF,sizeof(dis));//置为无穷大
memset(use,false,sizeof(use));//标记未使用过
int k;
for(int i=0;i<n;i++)
dis[i] = map[0][i];
use[0] = true;
double ans = 0,MIN;
for(int i=0;i<n-1;i++)
{
MIN = INF;
for(int j=1;j<n;j++)
if(!use[j]&&MIN>dis[j])
MIN = dis[k=j];
ans+=dis[k];
use[k] = true;
for(int j=1;j<n;j++)
if(!use[j])
dis[j] = min(dis[j],map[k][j]);
}
if(ans<=total)
printf("Need %.1lf miles of cable\n",ans);
else
printf("Not enough cable\n");
}
return 0;
}
相关文章推荐
- 图论-Prim最小生成树
- 数据结构之 图论---最小生成树(prim + kruskal)
- 图论中最小生成树算法-Prim(普里姆)算法、kruskal(克鲁斯卡尔避圈法)算法、破圈算法
- 图论-最小生成树-Prim
- 图论-带权图的最小生成树(Prim)算法
- 图论 最小生成树 Prim Kruskal POJ 3255 POJ 3723 POJ 3169
- 图论 邻接链表存储 BFS DFS 拓扑排序 最小生成树 KRUSKAL PRIM
- 图论 之 最小生成树 (Kruskal and Prim)
- 图论 || Prim(最小生成树)
- 夕拾算法进阶篇:34)最小生成树Prim(图论)
- 图论浅析--最小生成树之Prim
- 图论浅析--最小生成树之Prim
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- 图论九——最小生成树(prim)
- 图论--最小生成树总结(Prim&&Kruskal)
- CDOJ 1146 秋实大哥与连锁快餐店 Prim 最小生成树
- POJ Problem 2377 Cowtractors 【最小生成树Prim】
- c++ 最小生成树——Prim和Kruskal理解与分析
- hdu1162 Eddy's picture 最小生成树 prim
- HDU Problem 1875 畅通工程再续 【最小生成树Prim】