poj 1258 Agri-Net
来源:互联网 发布:蔡幸娟 星星知我心 编辑:程序博客网 时间:2024/05/19 13:58
poj 1258 Agri-Net
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 51094 Accepted: 21275
Description
Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course.
Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms.
Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm.
The distance between any two farms will not exceed 100,000.
Input
The input includes several cases. For each case, the first line contains the number of farms, N (3 <= N <= 100). The following lines contain the N x N conectivity matrix, where each element shows the distance from on farm to another. Logically, they are N lines of N space-separated integers. Physically, they are limited in length to 80 characters, so some lines continue onto others. Of course, the diagonal will be 0, since the distance from farm i to itself is not interesting for this problem.
Output
For each case, output a single integer length that is the sum of the minimum length of fiber required to connect the entire set of farms.
Sample Input
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
Sample Output
28
最小生成树——Prim算法
// N个顶点int N;struct Vertex { // 顶点编号 int v; // 到该顶点的权值 int w; Vertex(int vv, int ww): v(vv),w(ww) {}; bool operator < (const Vertex& v1) const{ return w > v1.w; }};// 邻接表vector<vector<Vertex> > G(MAX_VERTEX);// prim算法,最小生成树点构造性算法// 图,节点数和开始访问节点int prim(const vector<vector<Vertex> > &G, int n, int u) { // 优先队列 priority_queue<Vertex> pq; pq.push(G[u][u]); // 访问表 vector<int> visited(n); // 各顶点到已建好那部分树的距离 vector<int> dist(n); // 被加入访问表结点的数目 int visNum = 0; // 总权值 int totalW = 0; // 初始化各顶点为未访问,距离为无穷大 for(int i = 0; i < n; i++) { visited[i] = 0; dist[i] = INF; } // 结点未被遍历完并且队列不为空 while(visNum < N && !pq.empty()) { Vertex v = pq.top(); pq.pop(); // 已在访问表的结点不需要更新 if(visited[v.v]) { continue; } // 数据更新 totalW += v.w; visited[v.v] = 1; visNum++; // 更新新加入的邻边 for(int i = 0; i < G[v.v].size(); i++) { int k = G[v.v][i].v; int w = G[v.v][i].w; // k未被访问过并且到k的距离小于k到已使用点集的距离 if(!visited[k] && w < dist[k]) { dist[k] = w; pq.push(Vertex(k, w)); } } } // 图不连通 if(visNum < n) { return -1; } return totalW;}
源代码
#include <cstdio>#include <vector>#include <cstring>#include <queue>using namespace std;const int INF = 1 << 30;const int MAX_VERTEX = 100 + 10;// N个顶点int N;struct Vertex { // 顶点编号 int v; // 到该顶点的权值 int w; Vertex(int vv, int ww): v(vv),w(ww) {}; bool operator < (const Vertex& v1) const{ return w > v1.w; }};// 邻接表vector<vector<Vertex> > G(MAX_VERTEX);// prim算法,最小生成树点构造性算法// 图,节点数和开始访问节点int prim(const vector<vector<Vertex> > &G, int n, int u) { // 优先队列 priority_queue<Vertex> pq; pq.push(G[u][u]); // 访问表 vector<int> visited(n); // 各顶点到已建好那部分树的距离 vector<int> dist(n); // 被加入访问表结点的数目 int visNum = 0; // 总权值 int totalW = 0; // 初始化各顶点为未访问,距离为无穷大 for(int i = 0; i < n; i++) { visited[i] = 0; dist[i] = INF; } // 结点未被遍历完并且队列不为空 while(visNum < N && !pq.empty()) { Vertex v = pq.top(); pq.pop(); // 已在访问表的结点不需要更新 if(visited[v.v]) { continue; } // 数据更新 totalW += v.w; visited[v.v] = 1; visNum++; // 更新新加入的邻边 for(int i = 0; i < G[v.v].size(); i++) { int k = G[v.v][i].v; int w = G[v.v][i].w; // k未被访问过并且到k的距离小于k到已使用点集的距离 if(!visited[k] && w < dist[k]) { dist[k] = w; pq.push(Vertex(k, w)); } } } // 图不连通 if(visNum < n) { return -1; } return totalW;}int main() { while(scanf("%d", &N) != EOF) { // 清除数据 for(int i = 0; i < N; i++) { G[i].clear(); } // 邻接矩阵转化为邻接表 for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { int w; scanf("%d", &w); Vertex v(j, w); G[i].push_back(v); } } printf("%d\n", prim(G, N, 0)); } return 0;}
最小生成树Kruscal算法
const int INF = 1 << 30;const int MAX_VERTEX = 100 + 10;// N个顶点int N;struct EDGE { // 起始点 int s; // 终止点 int e; // 权值 int w; EDGE(int ss, int ee, int ww):s(ss),e(ee),w(ww) {}; bool operator < (const EDGE& e) const{ return w > e.w; }};priority_queue<EDGE> edges;// 并查集vector<int> parent(MAX_VERTEX);// 初始化void init(int N) { for(int i = 0; i < N; i++) { parent[i] = i; }}// 找到根节点int findSet(int p) { if(p == parent[p]) { return p; } else { return parent[p] = findSet(parent[p]); }}// s,e是否在一个集合bool isSomeSet(int s, int e) { return findSet(s) == findSet(e);}// 合并s,e的集合void unite(int s, int e) { int rootS = findSet(s); int rootE = findSet(e); if(rootS == rootE) { return; } parent[rootE] = rootS;}// kruscal算法,最小生成树边构造性算法// 节点数int kruscal(int N) { // 使用并查集 init(N); // 被加入的总边数 int visEdgeNum = 0; // 总权值 int totalW = 0; // 结点未被访问完且还有边没访问 while(visEdgeNum < N - 1 && !edges.empty()) { EDGE edge = edges.top(); edges.pop(); // 构成环 if(isSomeSet(edge.s, edge.e)) { continue; } // 数据更新 visEdgeNum++; totalW += edge.w; // 将点s,点e放入一个集合中 unite(edge.s, edge.e); } // 该图不是连通图 if(visEdgeNum != N - 1) { return -1; } return totalW;}
源代码
#include <cstdio>#include <queue>#include <vector>using namespace std;const int INF = 1 << 30;const int MAX_VERTEX = 100 + 10;// N个顶点int N;struct EDGE { // 起始点 int s; // 终止点 int e; // 权值 int w; EDGE(int ss, int ee, int ww):s(ss),e(ee),w(ww) {}; bool operator < (const EDGE& e) const{ return w > e.w; }};priority_queue<EDGE> edges;// 并查集vector<int> parent(MAX_VERTEX);// 初始化void init(int N) { for(int i = 0; i < N; i++) { parent[i] = i; }}// 找到根节点int findSet(int p) { if(p == parent[p]) { return p; } else { return parent[p] = findSet(parent[p]); }}// s,e是否在一个集合bool isSomeSet(int s, int e) { return findSet(s) == findSet(e);}// 合并s,e的集合void unite(int s, int e) { int rootS = findSet(s); int rootE = findSet(e); if(rootS == rootE) { return; } parent[rootE] = rootS;}// kruscal算法,最小生成树边构造性算法// 节点数int kruscal(int N) { // 使用并查集 init(N); // 被加入的总边数 int visEdgeNum = 0; // 总权值 int totalW = 0; // 结点未被访问完且还有边没访问 while(visEdgeNum < N - 1 && !edges.empty()) { EDGE edge = edges.top(); edges.pop(); // 构成环 if(isSomeSet(edge.s, edge.e)) { continue; } // 数据更新 visEdgeNum++; totalW += edge.w; // 将点s,点e放入一个集合中 unite(edge.s, edge.e); } // 该图不是连通图 if(visEdgeNum != N - 1) { return -1; } return totalW;}int main() { while(scanf("%d", &N) != EOF) { // 清楚数据 while(!edges.empty()) { edges.pop(); } // 邻接矩阵转化为邻接表 for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { int w; scanf("%d", &w); if(w != 0) { edges.push(EDGE(i, j, w)); } } } printf("%d\n", kruscal(N)); } return 0;}
- POJ 1258 Agri-Net
- POJ 1258 Agri-Net
- POJ 1258 Agri-Net
- poj 1258-Agri-net
- poj 1258 Agri-Net
- poj 1258 Agri-Net
- POJ+1258++Agri-Net
- Poj 1258 Agri-Net
- poj 1258 Agri-Net
- poj 1258 Agri-Net
- poj 1258 Agri-Net
- POJ 1258 Agri-Net
- POJ 1258 Agri-Net
- POJ 1258 Agri-Net
- poj-1258-Agri-Net
- poj-1258 Agri-Net
- Poj 1258 Agri-Net
- POJ 1258 - Agri-Net
- SAX 解析XML 将xml转换成javaBean
- jQuery事件绑定on()、bind()与delegate() 方法详解
- 64位Win7下安装并配置Python3的深度学习库:Theano
- C语言 发生的错误记录(1):conlicting types for ‘fuction_name’
- 《Android开发艺术探索读书笔记二》
- poj 1258 Agri-Net
- Android中部分特殊的显示
- C++逐位拷贝和逐成员拷贝的区别
- 62. Unique Paths
- hello world Cacti url 作图
- 1086. Tree Traversals Again (25)
- HDOJ 2199 Can you solve this equation?
- hadoop:基于Java API实现的编译
- 圣杯布局