时间限制:
10000ms
单点时限:
1000ms
内存限制:
256MB
-
5 29 1 2 674 2 3 249 3 4 672 4 5 933 1 2 788 3 4 147 2 4 504 3 4 38 1 3 65 3 5 6 1 5 865 1 3 590 1 4 682 2 4 227 2 4 636 1 4 312 1 3 143 2 5 158 2 3 516 3 5 102 1 5 605 1 4 99 4 5 224 2 4 198 3 5 894 1 5 845 3 4 7 2 4 14 1 4 185
样例输出
-
92
-
题解:其实和克鲁斯卡尔的思想一样的,每次都查找最小边。由于使用了优先队列,排序了使得复杂度降为了nlogn。
-
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace std; const int INF = 100005; struct Node { int to; int dis; Node(int a,int b) { to = a; //邻接点 dis = b; } bool operator< (Node t) const //排序 { return dis > t.dis; } }; vector<Node> vec[INF]; priority_queue<Node> q; bool visited[INF]; void prime(int& ans,int n) { for(int i = 0;i < vec[1].size();i++) //与1相连的入队 { q.push(vec[1][i]); } visited[1] = true; for(int i = 1;i < n;i++) //n-1条边 { while(!q.empty()) //每次找边最小的 { Node t = q.top(); q.pop(); if(visited[t.to]) { continue; } ans += t.dis; visited[t.to] = true; for(int j = 0;j < vec[t.to].size();j++) //更新队列 { Node p = vec[t.to][j]; if(!visited[p.to]) { q.push(p); } } break; } } printf("%d\n",ans); for(int i = 1;i <= n;i++) { vec[i].clear(); } while(!q.empty()) { q.pop(); } } int main() { int n,m; int u,v,dis; cin>>n>>m; for(int i = 0;i < m;i++) { scanf("%d%d%d",&u,&v,&dis); vec[u].push_back(Node(v,dis)); vec[v].push_back(Node(u,dis)); } memset(visited,false,sizeof(visited)); int ans = 0; prime(ans,n); return 0; }
描述
回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生了一个疑问,究竟这样的算法在稀疏图上比Prim优化之处在哪里呢?
提示:没有无缘无故的优化!输入
每个测试点(输入文件)有且仅有一组测试数据。
在一组测试数据中:
第1行为2个整数N、M,表示小Hi拥有的城市数量和小Hi筛选出路线的条数。
接下来的M行,每行描述一条路线,其中第i行为3个整数N1_i, N2_i, V_i,分别表示这条路线的两个端点和在这条路线上建造道路的费用。
对于100%的数据,满足N<=10^5, M<=10^6,于任意i满足1<=N1_i, N2_i<=N, N1_i≠N2_i, 1<=V_i<=10^3.
对于100%的数据,满足一定存在一种方案,使得任意两座城市都可以互相到达。
输出
对于每组测试数据,输出1个整数Ans,表示为了使任意两座城市都可以通过所建造的道路互相到达至少需要的建造费用。