专题四 第十道题
2016-07-03 22:32
330 查看
1.题目编号:1007
2.简单题意:在2100年由于海平面上升,大多数的城市消失了,尽管有些存活下来的城市是相连的,但是大多数的城市是不相连的,政府想建一些道路将这些城市再次连接起来,但是他们并不像花太多的钱。题目给出了n个存活的城市,m条可以选择建的道路,和k个一直相连的城市。然后接下来m行,每行有三个数c,p,q,即从p到q健道路需要花费c元,接下来是k行,t个相连接的城市的数量,及他们的Id号。
3.解题思路形成过程:
一看是将所有的城市连接起来,而且需要花费最少,就想到最小生成树的问题,这道题和前面的求最小生成树的方法一样就是输入的时候不一样。用prim算法。
4.感悟:
这些题要不就是最小生成树,要不就是最短路径,可以套用模板。
5.AC的代码:
#include<stdio.h>
#include<string.h>
#define N 600
#define INF 0x7ffffff
int ll
;
int low
,vis
;
int n;
int prim(){
int pos,res=0;
memset(vis,0,sizeof(vis));
vis[1]=1;
pos=1;
for(int i=1;i<=n;i++)
if(i!=pos) low[i]=ll[pos][i];
for(int i=1;i<n;i++){
int minn=INF;
pos=-1;
for(int j=1;j<=n;j++)
if(!vis[j] && minn>low[j]){
minn=low[j];
pos=j;
}
if(pos==-1) return -1;
res+=minn;
vis[pos]=1;
for(int j=1;j<=n;j++)
if(!vis[j] && low[j]>ll[pos][j])
low[j]=ll[pos][j];
}
return res;
}
int main() {
int t,m,k;
int p,q,c;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
ll[i][j]=INF;
for(int i=0;i<m;i++){
scanf("%d%d%d",&p,&q,&c);
if(ll[p][q]>c)
ll[p][q]=ll[q][p]=c;
}
for(int i=0;i<k;i++){
scanf("%d",&c);
scanf("%d",&p);
c--;
while(c--){
scanf("%d",&q);
ll[p][q]=ll[q][p]=0;
p=q;
}
}
int ss=prim();
printf("%d\n",ss);
}
return 0;
}
2.简单题意:在2100年由于海平面上升,大多数的城市消失了,尽管有些存活下来的城市是相连的,但是大多数的城市是不相连的,政府想建一些道路将这些城市再次连接起来,但是他们并不像花太多的钱。题目给出了n个存活的城市,m条可以选择建的道路,和k个一直相连的城市。然后接下来m行,每行有三个数c,p,q,即从p到q健道路需要花费c元,接下来是k行,t个相连接的城市的数量,及他们的Id号。
3.解题思路形成过程:
一看是将所有的城市连接起来,而且需要花费最少,就想到最小生成树的问题,这道题和前面的求最小生成树的方法一样就是输入的时候不一样。用prim算法。
4.感悟:
这些题要不就是最小生成树,要不就是最短路径,可以套用模板。
5.AC的代码:
#include<stdio.h>
#include<string.h>
#define N 600
#define INF 0x7ffffff
int ll
;
int low
,vis
;
int n;
int prim(){
int pos,res=0;
memset(vis,0,sizeof(vis));
vis[1]=1;
pos=1;
for(int i=1;i<=n;i++)
if(i!=pos) low[i]=ll[pos][i];
for(int i=1;i<n;i++){
int minn=INF;
pos=-1;
for(int j=1;j<=n;j++)
if(!vis[j] && minn>low[j]){
minn=low[j];
pos=j;
}
if(pos==-1) return -1;
res+=minn;
vis[pos]=1;
for(int j=1;j<=n;j++)
if(!vis[j] && low[j]>ll[pos][j])
low[j]=ll[pos][j];
}
return res;
}
int main() {
int t,m,k;
int p,q,c;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
ll[i][j]=INF;
for(int i=0;i<m;i++){
scanf("%d%d%d",&p,&q,&c);
if(ll[p][q]>c)
ll[p][q]=ll[q][p]=c;
}
for(int i=0;i<k;i++){
scanf("%d",&c);
scanf("%d",&p);
c--;
while(c--){
scanf("%d",&q);
ll[p][q]=ll[q][p]=0;
p=q;
}
}
int ss=prim();
printf("%d\n",ss);
}
return 0;
}
相关文章推荐
- android 视频录制 混淆打包 之native层 异常的解决
- VC中dll的lib文件和dll有什么不同?
- VC中创建不可改变大小的窗口,及其限制窗口大小的办法
- 【ASP.NET】——有缘千里来相会
- Android跨进程通信
- Spring中提供的util CollectionUtils
- mac 下安装pip
- VC中枚举所有的任务,任务管理器的一些资料的整理
- shell学习笔记
- python开发之路Day17-算法设计(冒泡排序、选择排序、插入排序、二叉树)
- Android横竖屏切换小结
- laravel 框架学习(二)
- 新的一年,我想要做到的。
- java简单排序-插入排序
- Visual C++开发工具与调试技巧整理
- [转]Android的23种设计模式
- 利用Metrics+influxdb+grafana构建监控平台
- ZooKeeper入门(四)
- hadoop--初识hadoop
- 保证应用程序只有一个实例在运行