poj1861解题报告
2015-07-12 16:58
381 查看
题目大意:给出n个点和m条边,求出最小生成树,输出最小生成树权值最大的第一条边,然后再输出最小生成树的边数,
解题思路:直接上kruskal的模板即可,但需要改一下,一是要记录最长边,二是要记录生成了几条边,三是要记录要使用了哪些边(用两对结点表示)
注意点:1.样例是错的,WQNMLGB
2.输出的第二行不是总长度,是生成树的边数
解题思路:直接上kruskal的模板即可,但需要改一下,一是要记录最长边,二是要记录生成了几条边,三是要记录要使用了哪些边(用两对结点表示)
注意点:1.样例是错的,WQNMLGB
2.输出的第二行不是总长度,是生成树的边数
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int maxn=15000+100; int u[maxn],v[maxn],w[maxn],p[maxn],r[maxn],n,m,length,vis[maxn],cnt;//数组u储存起始点,数组v存储终点,数组w存储边权,m是边数,n是点数 int cmp(const int i,const int j) {return w[i]<w[j];} int find(int x) {return p[x]==x?x:p[x]=find(p[x]);} int kruskal() { int x,y,i,ans=-1; length=0; cnt=0; for(i=0;i<n;i++) p[i]=i;//初始化并查集 for(i=0;i<m;i++) r[i]=i; sort(r,r+m,cmp);//根据边权排序 for(i=0;i<m;i++) { int e=r[i];x=find(u[e]);y=find(v[e]); if(x!=y) {ans += w[e];length=max(length,w[e]);vis[r[i]]=1;p[x]=y;cnt++;} if(cnt==n-1) return ans; } if(cnt<n-1) ans=0;//n个点的数有n条边 return ans; } int main() { int ans; while(scanf("%d%d",&n,&m)!=EOF) { length=0; cnt=0; memset(vis,0,sizeof(vis)); for(int i=0;i<m;i++) scanf("%d%d%d",&u[i],&v[i],&w[i]); ans=kruskal(); printf("%d\n%d\n",length,cnt); for(int i=0;i<m;i++) if(vis[i]) printf("%d %d\n",u[i],v[i]); } }
相关文章推荐
- Python下opencv使用笔记(七)(图像梯度与边缘检测)
- [开发工具]_[VS2010]_[vs2010的一个bug-使用stringstream时出现]
- 学习笔记_监听器
- CSS3学习(一) css基础补充
- 使用Gitblit在Windows平台上安装与配置Git Server
- Java的访问控制符
- Html 语法学习笔记二
- Html 语法学习笔记二
- file_operation结构体详解
- android学习路线:如何成长为高级工程师
- Java反编译
- Scala入门第一篇
- ListView的工作原理
- [LeetCode] Invert Binary Tree
- 修改MyEclipse的Servlet的生成模板
- 【Android】关于使用空格对齐文字
- Android Studio 项目目录结构
- android 程序中禁止屏幕旋转和重启Activity
- 基于cocos2d-x的游戏客户端优化
- 100万并发连接服务器笔记之1M并发连接目标达成