FZU 2087 统计树边【MST相关】
2016-04-14 13:20
357 查看
![](http://acm.fzu.edu.cn/image/problem.gif)
Problem 2087 统计树边
Accept: 212 Submit: 651
Time Limit: 1000 mSec Memory Limit : 32768 KB
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Problem Description
在图论中,树:任意两个顶点间有且只有一条路径的图。生成树:包含了图中所有顶点的一种树。
最小生成树:对于连通的带权图(连通网)G,其生成树也是带权的。生成树T各边的权值总和称为该树的权,权最小的生成树称为G的最小生成树(Minimum Spanning Tree)。最小生成树可简记为MST。
但是,对于一个图而言,最小生成树并不是唯一的。
现在,给你一个连通的有权无向图,图中不包含有自环和重边,你的任务就是寻找出有多少条边,它至少在一个最小生成树里。图保证连通。
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Input
输入数据第一行包含一个整数T,表示测试数据的组数。对于每组测试数据:第一行包含两个整数n,m(1<n<100000,n-1<m<100000),接下来m行,每行三个整数a,b,v(1<=a,b<=n,1<v<500),表示第i条路线连接景点A和景点B,距离是V。两个数字之间用空格隔开。
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Output
对于每组测试数据,输出一行,包含一个整数,表示满足条件的边的个数。
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Sample Input
14 5
1 2 101
1 3 100
2 3 2
2 4 2
3 4 1
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Sample Output
4
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Source
福州大学第九届程序设计竞赛思路:用kruskal算法模拟生成树的过程。同时也是一个贪心生成树的过程,我们知道,生成的树的边权值和是一定的,那么对于边的替换的值也是能够确定的:只有权值相同的边才有可能是另一种生成树方法的边。
然后我就呆萌的记录有多少重边权值的边,然后加上n-1,开开心心的提交,实力WA。一组数据就可以干掉我:
3 3
1 2 1
1 2 2
2 3 1
所以记得一定不要跟我犯一样的错误,我们需要的是动态判断一条边权值相同的边能否可能是另一种生成树方法的边。我们直接在kruskal算法过程中加上动态判断的成分就可以了,那么要如何判断呢?遍历每一条边的时候,如果有相同权值的边,像kruskal一样的判断条件,判断这条边能否加入生成树中即可。
kruskal算法判断一条边是否能够贪心的加入生成树中:
for(int i=0;i<m;i++)
{
if(find(a[i].x)!=find(a[i].y))
{
zhongquanzhi+=a[i].w;
merge(a[i].x,a[i].y);
}
}
我们对同权值的边判断能否加入生成树中,并且别忘记对边要进行入树:
for(int i=0;i<m;i=j) { for(j=i;a[i].w==a[j].w;j++) { if(find(a[j].x)!=find(a[j].y)) { output++; } } for(j=i;a[i].w==a[j].w;j++) { if(find(a[j].x)!=find(a[j].y)) { merge(a[j].x,a[j].y); } } }
完整的AC代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int f[1000050]; struct path { int x,y,w; }a[100050]; int cmp(path a,path b) { return a.w<b.w; } int find(int x) { return f[x] == x ? x : (f[x] = find(f[x])); } void merge(int a,int b) { int A,B; A=find(a); B=find(b); if(A!=B) f[B]=A; } int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { f[i]=i; } for(int i=0;i<m;i++) { scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); } sort(a,a+m,cmp); int output=0; int j; for(int i=0;i<m;i=j) { for(j=i;a[i].w==a[j].w;j++) { if(find(a[j].x)!=find(a[j].y)) { output++; } } for(j=i;a[i].w==a[j].w;j++) { if(find(a[j].x)!=find(a[j].y)) { merge(a[j].x,a[j].y); } } } printf("%d\n",output); } }
相关文章推荐
- 234. Palindrome Linked List
- Android Studio 环境配置优化
- android studio多渠道打包,且根据buildConfig属性判断为哪个渠道升级或者实现不同业务逻辑
- QtCreator:项目中文件按类别放入不同子文件夹
- linux模块导出符号 EXPORT_SYMBOL_GPL EXPORT_SYMBOL
- Android 代码动态改变View的属性
- JDK、Tomcat、ANT及Eclipse常用配置
- LVS Funnat 编译安装使用
- codeforces 660A
- MVC下拉框Html.DropDownList 和DropDownListFor 的常用方法
- 求助:提示错误:warning C206: 'dispay': missing function-prototype
- spring新线程中注入为空指针的问题
- linux字符设备驱动 cdev
- Struts2验证框架 图片验证码 自定义验证器
- Putty实现Linux与Windows互传文件
- One Way Roads(搜索)
- Back to Underworld(搜索)
- ES5中新增的Array方法详细说明
- (五)IBM Sterling OMS 环境构建之环境变量参数配置及语言包
- iOS开发总结之自定义等高cell03-xib