Program4_E
2016-06-19 11:22
211 查看
我现在做的事第四专题编号为1005的试题,具体内容如下所示:
Total Submission(s) : 66 Accepted Submission(s) : 20
[align=left]Problem Description[/align]
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。<br>
[align=left]Input[/align]
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。<br><br>当N为0时输入结束。
[align=left]Output[/align]
每个测试用例的输出占一行,输出全省畅通需要的最低成本。
[align=left]Sample Input[/align]
3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0
[align=left]Sample Output[/align]
3
1
0
简单题意:
要实现全省任何两个村庄都能相连,求修路的最少成本
解题思路:
从题意中我们知道,已经修过路的只需要从未修路的村庄中找到一个离已经连通的图中最近的一个点,将其并入到连通图即可,由此可看是最小生成树
可以从边考虑,即利用普利姆算法或者克努斯卡尔算法求最小生成树,边比较多的时候普利姆算法比较高效,否则另一个较高效普利姆算法。
编写代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define size 105
#define INF 0x7ffffff
int g[size][size];
int dis[size];
bool vis[size];
int n,m;
void init()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
g[i][j]=INF;
}
void Prim(int s,int e)
{
int ans=0;
for(int i=1;i<=n;i++)
{
dis[i]=g[s][i];
vis[i]=false;
}
vis[s]=true;
dis[s]=0;
for(int i=1;i<n;i++)
{
int minnum=INF;
int temp=0;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]<minnum)
{
temp=j;
minnum=dis[j];
ans+=minnum;
vis[temp]=true;
for(int j=1;j<=n;j++)
if(!vis[j]&&g[temp][j]!=INF&&g[temp][j]<dis[j])
dis[j]=g[temp][j];
}
printf("%d\n",ans);
}
}
int main()
{
while(scanf("%d",&n),n)
{
int m=n*(n-1)/2;
for(int i=0;i<m;i++)
{
int s,e,v,flag;
scanf("%d%d%d%d",&s,&e,&v,&flag);
if(flag)
g[s][e]=g[e][s]=0;
else
g[s][e]=g[e][s]=v;
}
Prim(1,n);
}
return 0;
}
Problem E
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)Total Submission(s) : 66 Accepted Submission(s) : 20
[align=left]Problem Description[/align]
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。<br>
[align=left]Input[/align]
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。<br><br>当N为0时输入结束。
[align=left]Output[/align]
每个测试用例的输出占一行,输出全省畅通需要的最低成本。
[align=left]Sample Input[/align]
3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0
[align=left]Sample Output[/align]
3
1
0
简单题意:
要实现全省任何两个村庄都能相连,求修路的最少成本
解题思路:
从题意中我们知道,已经修过路的只需要从未修路的村庄中找到一个离已经连通的图中最近的一个点,将其并入到连通图即可,由此可看是最小生成树
可以从边考虑,即利用普利姆算法或者克努斯卡尔算法求最小生成树,边比较多的时候普利姆算法比较高效,否则另一个较高效普利姆算法。
编写代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define size 105
#define INF 0x7ffffff
int g[size][size];
int dis[size];
bool vis[size];
int n,m;
void init()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
g[i][j]=INF;
}
void Prim(int s,int e)
{
int ans=0;
for(int i=1;i<=n;i++)
{
dis[i]=g[s][i];
vis[i]=false;
}
vis[s]=true;
dis[s]=0;
for(int i=1;i<n;i++)
{
int minnum=INF;
int temp=0;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]<minnum)
{
temp=j;
minnum=dis[j];
ans+=minnum;
vis[temp]=true;
for(int j=1;j<=n;j++)
if(!vis[j]&&g[temp][j]!=INF&&g[temp][j]<dis[j])
dis[j]=g[temp][j];
}
printf("%d\n",ans);
}
}
int main()
{
while(scanf("%d",&n),n)
{
int m=n*(n-1)/2;
for(int i=0;i<m;i++)
{
int s,e,v,flag;
scanf("%d%d%d%d",&s,&e,&v,&flag);
if(flag)
g[s][e]=g[e][s]=0;
else
g[s][e]=g[e][s]=v;
}
Prim(1,n);
}
return 0;
}
相关文章推荐
- struct 的用法
- Android_RxJava最简单的用法
- Thread类的使用
- Android初级教程理论知识(第八章网络编程一)
- Android初级教程理论知识(第八章网络编程一)
- Exynos4412 IIC总线驱动开发(二)—— IIC 驱动开发
- 专题四1005
- python之文件切割保存
- 阶乘末尾 0 的个数
- matlab颜色映射colormap() pcolor()
- MyBatis-高级映射:一对一
- Exynos4412 IIC 总线驱动开发相关问题总结
- 冒泡排序
- C#快速生成数据数组
- Exynos4412 中断驱动开发相关问题总结
- 妙用php中的register_shutdown_function和fastcgi_finish_request
- java基础知识:break语句和continue语句
- 如何创建线程
- Exynos4412 中断处理流程详解
- MarkDown的vim插件安装