hdu 1863 畅通工程 (最小生成树)
2016-07-10 22:49
429 查看
解题思路:这道题做了两次,第一次做的时候还不知道有最小生成树这种东西,以为是最短路问题,就顺着思路想,不过并没有什么结果,当时误打误撞想出了一种这种问题的解法,就是每次选取能够让这棵树延长的最短的那一条边,不过鉴于算法复杂度过高就没有实现,后来学习了最小生成树算法,现在看来这道题就很直接了,就是一个裸的Kruskal算法。这个算法的核心就在于每次选取一条既不能使图形成回路又是最短的边,也就是一个并查集的过程。
代码:#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
#define inf 0x3f3f3f3f
using namespace std;
typedef struct P
{
int point1;
int point2;
int val;
}p;
bool compare(p a,p b)
{
return a.val<=b.val;
}
p edge[10001];
int city[105];
int getcity(int point)
{
if(city[point] == point)
{
return point;
}
else
{
city[point] = getcity(city[point]);
return city[point];
}
}
bool connect(int point1,int point2)
{
int t1,t2;
t1 = getcity(point1);
t2 = getcity(point2);
if(t1!=t2)
{
city[t2] = t1;
return true;
}
return false;
}
int main()
{
int n,m;
int i;
int cnt,sum;
while(cin>>n>>m && n)
{
cnt = 0,sum = 0;
for(i=0;i<n;i++)
{
cin>>edge[i].point1>>edge[i].point2>>edge[i].val;
}
sort(edge,edge+n,compare);
for(i=1;i<=m;i++)//特别注意这里的序号要从1开始,与题目要求保持一致,因为没注意这里WA了一次
city[i] = i;
for(i=0;i<n;i++)
{
if(connect(edge[i].point1,edge[i].point2))
{
cnt++;
sum += edge[i].val;
}
if(cnt==m-1)
break;
}
if(cnt!=m-1)
cout << '?' << endl;
else
cout << sum << endl;
}
return 0;
}
代码:#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
#define inf 0x3f3f3f3f
using namespace std;
typedef struct P
{
int point1;
int point2;
int val;
}p;
bool compare(p a,p b)
{
return a.val<=b.val;
}
p edge[10001];
int city[105];
int getcity(int point)
{
if(city[point] == point)
{
return point;
}
else
{
city[point] = getcity(city[point]);
return city[point];
}
}
bool connect(int point1,int point2)
{
int t1,t2;
t1 = getcity(point1);
t2 = getcity(point2);
if(t1!=t2)
{
city[t2] = t1;
return true;
}
return false;
}
int main()
{
int n,m;
int i;
int cnt,sum;
while(cin>>n>>m && n)
{
cnt = 0,sum = 0;
for(i=0;i<n;i++)
{
cin>>edge[i].point1>>edge[i].point2>>edge[i].val;
}
sort(edge,edge+n,compare);
for(i=1;i<=m;i++)//特别注意这里的序号要从1开始,与题目要求保持一致,因为没注意这里WA了一次
city[i] = i;
for(i=0;i<n;i++)
{
if(connect(edge[i].point1,edge[i].point2))
{
cnt++;
sum += edge[i].val;
}
if(cnt==m-1)
break;
}
if(cnt!=m-1)
cout << '?' << endl;
else
cout << sum << endl;
}
return 0;
}
相关文章推荐
- LeetCode第二天
- CSP考试 2013年12月第5题 I’m stuck! C语言实现
- Python 字典<->元组<->列表<->字符串 互转方法
- PHP Array方法归纳总结
- HDU1085(母函数)
- TensorFlow 深度学习笔记
- HDU1394 Minimum Inversion Number
- mmap内存映射
- 全国大学生信息安全竞赛writeup--暗号(reverse300)
- hdu 4899 Hero meet devil
- Java工程师成神之路
- 读取系统自带的数据库
- 读取系统自带的数据库
- 关于int main( int argc, char* argv[] ) 中arg和argv参数的解析及调试
- PHP判断是否是移动设备访问
- 毕业五年之感想--写给自己的话
- php实现的视频质量检测配置页面,异步调用不退出的进程:
- 2016第28周日
- 错误: symbol lookup error: /usr/local/lib/libreadline.so.6: undefined symbol: PC
- R语言笔记六