畅通工程

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24323    Accepted Submission(s): 10621

Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
 
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
 
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
 
Sample Input
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
 
Sample Output
3
?
 

先引用百度百科

先构造一个只含 n 个顶点、而边集为空的子图,把子图中各个顶点看成各棵树上的根结点,之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,即把两棵树合成一棵树,反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直到森林中只有一棵树,也即子图中含有
n-1 条边为止。

最后一句很重要,停止条件是子图中含有n-1条边为止。

还有就是选取每一条边的时候要看看是否能与之前已选中的构成回路,不构成回路则选择一条距离最短的,若能构成回路则舍弃。

嗯这题无聊玩了一下操作符重载(刚开始写反了输出的结果比较大。),比较有意思的。鉴于sort的复杂度不大两者应该没啥差别,就是不用vector的情况下空间可以节省一点……没错我就是这么无聊= =

sort写法:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long LL;
const int N=1010;
struct info
{
int a;
int b;
int val;
info(){a=b=val=0;}
}; info G[3*N];
int vis[N]; void init()
{
MM(G);
for (int i=0; i<N; i++)
vis[i]=i;
}
bool cmp(const info &a,const info &b)
{
return a.val<b.val;
}
inline int find(int a)
{
if(vis[a]!=a)
return vis[a]=find(vis[a]);
return vis[a];
}
inline int merge(const int &a,const int &b)
{
int aa=find(a),bb=find(b);
if(aa!=bb)
{
vis[bb]=aa;
return 1;
}
return 0;
} int main(void)
{
int tcase,i,x,y,val,n,m;
scanf("%d",&tcase);
while (tcase--)
{
scanf("%d%d",&n,&m);
init();
int ans=0,cnt=0;
for (i=1; i<=m; i++)
{
scanf("%d%d%d",&G[i].a,&G[i].b,&G[i].val);
}
sort(G+1,G+m+1,cmp);
for (i=1; i<=m; i++)
{
if(cnt==n-1)
break;
if(merge(G[i].a,G[i].b))
{
cnt++;
ans+=G[i].val;
}
}
cnt==n-1?printf("%d\n",ans):puts("-1");
}
return 0;
}

优先队列写法:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long LL;
const int N=1010; struct info
{
int a;
int b;
int val;
bool operator<(const info &b) const
{
return val>b.val;
}
}; info G;
int vis[N];
priority_queue<info> Q; void debug(priority_queue<info> q)
{
while (!q.empty())
{
cout<<q.top().a<<" "<<q.top().b<<endl;
q.pop();
}
} void init()
{
for (int i=0; i<N; i++)
{
vis[i]=i;
}
while (!Q.empty())
Q.pop();
}
inline int find(int a)
{
if(vis[a]!=a)
return vis[a]=find(vis[a]);
return vis[a];
}
inline bool merge(int a,int b)
{
int aa=find(a),bb=find(b);
if(aa!=bb)
{
vis[bb]=aa;
return true;
}
return false;
}
int main(void)
{
int tcase,i,j,x,y,val,n,m;
scanf("%d",&tcase);
while (tcase--)
{
scanf("%d%d",&n,&m);
init();
int ans=0,cnt=0;
for (i=0; i<m; i++)
{
scanf("%d%d%d",&G.a,&G.b,&G.val);
Q.push(G);
}
//debug(Q);
while (!Q.empty())
{
info t=Q.top();
Q.pop();
if(cnt==n-1)
break;
if(merge(t.a,t.b))
{
cnt++;
ans+=t.val;
}
}
cnt==n-1?printf("%d\n",ans):puts("-1");
}
return 0;
}

ACM程序设计选修课——Problem E:(ds:图)公路村村通(优先队列或sort+克鲁斯卡尔+并查集优化)的更多相关文章

  1. ACM程序设计选修课——Problem E:(ds:图)公路村村通(Prim)

    问题 E: (ds:图)公路村村通 时间限制: 1 Sec  内存限制: 128 MB 提交: 9  解决: 5 题目描述 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本, ...

  2. ACM程序设计选修课——Problem F:(ds:图)旅游规划(优先队列+SPFA)

    问题 F: (ds:图)旅游规划 时间限制: 1 Sec  内存限制: 128 MB 提交: 14  解决: 4 题目描述 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路 ...

  3. ACM程序设计选修课——Problem D: (ds:树)合并果子(最优二叉树赫夫曼算法)

    Problem D: (ds:树)合并果子 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 80  Solved: 4 [Submit][Status][ ...

  4. pta08-图7 公路村村通 (30分)

    08-图7 公路村村通   (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...

  5. pat06-图6. 公路村村通(30)

    06-图6. 公路村村通(30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的 ...

  6. 7-6 公路村村通(30 分) 【prime】

    7-6 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤10 ...

  7. 7-10 公路村村通(30 分)(最小生成树Prim算法)

    7-10 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1 ...

  8. PTA 7-1 公路村村通 (30分)

    PTA 7-1 公路村村通 (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...

  9. PTA 08-图7 公路村村通 (30分)

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数NN(\le 1000≤1000)和候选道 ...

随机推荐

  1. 【转】Deactivating your reflector

    原文:http://blog.csdn.net/cxwl3sxl/article/details/8072195 背景: 因为想破解一个.net写的程序,需要在visual studio 2010中使 ...

  2. CPP-STL:vector的内存释放

    1. vector容器的内存自增长 与其他容器不同,其内存空间只会增长,不会减小.先来看看"C++ Primer"中怎么说:为了支持快速的随机访问,vector容器的元素以连续方式 ...

  3. 谈谈TCP的四次挥手

    “挥手”是为了终止连接,TCP四次挥手的流程图如下: (在socket编程中,可以由客户端或服务端进行close操作来进行) 下面的图是由客户端主动关闭连接 MSL是什么?最长报文段寿命 ------ ...

  4. javaweb基础(6)_servlet配置参数

    一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...

  5. scanf()的使用

    scanf函数称为格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中. 如下面代码: #include<stdio.h> int main() { int a,b; sca ...

  6. 1_HDFS理论及安装部署

    一.hadoop简介 1.hadoop的初衷是为了解决Nutch的海量数据爬取和存储的需要,HDFS来源于google的GFS,MapReduce来源于Google的MapReduce,HBase来源 ...

  7. AutoLayout处理UITableView动态高度

    我们经常会遇到UITableViewCell的高度要跟随内容而调整,在未引入AutoLayout之前,我们使用以下方法计算Label高度,然后heightForRowAtIndexPath中返回计算的 ...

  8. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  9. 学习笔记(五): Feature Crosses

    目录 Feature Crosses Encoding Nonlinearity Kinds of feature crosses Glossay Crossing One-Hot Vectors P ...

  10. 批量ping IP并检测IP延迟率和丢包率脚本

    脚本文件如下: #!/bin/bash #Author:Mr.Ding #Created Time:2018-08-26 07:23:44 #Name:ping.sh #Description: sh ...