题目链接:HDU 1102 Constructing Roads
3 0 990 692 990 0 179 692 179 0 1 1 2
179
#include <iostream> #include <cstdio> #include <queue> using namespace std; #define maxn 110 #define INF 0xffff int g[maxn][maxn]; int n; struct node { int v, key; friend bool operator<(node a, node b) { return a.key > b.key; } }; bool visited[maxn]; node vx[maxn]; priority_queue<node> q; void Prim() { for(int i = 1; i <= n; i++) { vx[i].v = i; vx[i].key = INF; visited[i] = false; } vx[1].key = 0; q.push(vx[1]); while(!q.empty()) { node nd = q.top(); q.pop(); int st = nd.v; if(visited[st]) continue; visited[st] = true; for(int j = 1; j <= n; j++) { if(j != st && !visited[j] && vx[j].key > g[st][j]) { vx[j].key = g[st][j]; q.push(vx[j]); } } } } int main() { int m, a, b; while(~scanf("%d", &n)) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) scanf("%d", &g[i][j]); g[i][i] = INF; } scanf("%d", &m); while(m--) { scanf("%d%d", &a, &b); g[a][b] = g[b][a] = 0; } Prim(); int ans = 0; for(int i = 1; i <= n; i++) ans += vx[i].key; printf("%d\n", ans); } return 0; }
#include <iostream> #include <cstdio> #include <vector> #include <queue> using namespace std; #define maxn 110 //最大顶点个数 int n, m; //顶点数,边数 struct arcnode //边结点 { int vertex; //与表头结点相邻的顶点编号 int weight; //连接两顶点的边的权值 arcnode * next; //指向下一相邻接点 arcnode() {} arcnode(int v,int w):vertex(v),weight(w),next(NULL) {} }; struct vernode //顶点结点,为每一条邻接表的表头结点 { int vex; //当前定点编号 arcnode * firarc; //与该顶点相连的第一个顶点组成的边 }Ver[maxn]; void Init() //建立图的邻接表需要先初始化,建立顶点结点 { for(int i = 1; i <= n; i++) { Ver[i].vex = i; Ver[i].firarc = NULL; } } void Insert(int a, int b, int w) //尾插法,插入以a为起点,b为终点,权为w的边,效率不如头插,但是可以去重边 { arcnode * q = new arcnode(b, w); if(Ver[a].firarc == NULL) Ver[a].firarc = q; else { arcnode * p = Ver[a].firarc; if(p->vertex == b) { if(p->weight > w) p->weight = w; return ; } while(p->next != NULL) { if(p->next->vertex == b) { if(p->next->weight > w); p->next->weight = w; return ; } p = p->next; } p->next = q; } } void Insert2(int a, int b, int w) //头插法,效率更高,但不能去重边 { arcnode * q = new arcnode(b, w); if(Ver[a].firarc == NULL) Ver[a].firarc = q; else { arcnode * p = Ver[a].firarc; q->next = p; Ver[a].firarc = q; } } struct node //保存key值的结点 { int v; int key; friend bool operator<(node a, node b) //自定义优先级,key小的优先 { return a.key > b.key; } }; #define INF 0xfffff //权值上限 bool visited[maxn]; //是否已经加入树 node vx[maxn]; //保存每个结点与其父节点连接边的权值 priority_queue<node> q; //优先队列stl实现 void Prim() //s表示根结点 { for(int i = 1; i <= n; i++) //初始化 { vx[i].v = i; vx[i].key = INF; visited[i] = false; } vx[1].key = 0; q.push(vx[1]); while(!q.empty()) { node nd = q.top(); //取队首,记得赶紧pop掉 q.pop(); if(visited[nd.v]) //注意这一句的深意,避免很多不必要的操作 continue; visited[nd.v] = true; arcnode * p = Ver[nd.v].firarc; while(p != NULL) //找到所有相邻结点,若未访问,则入队列 { if(!visited[p->vertex] && p->weight < vx[p->vertex].key) { vx[p->vertex].key = p->weight; vx[p->vertex].v = p->vertex; q.push(vx[p->vertex]); } p = p->next; } } } int main() { int m, a, b, x; while(~scanf("%d", &n)) { Init(); for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { scanf("%d", &x); if(x != 0) Insert2(i, j, x); } } scanf("%d", &m); while(m--) { scanf("%d%d", &a, &b); Insert(a, b, 0); Insert(b, a, 0); } Prim(); int ans = 0; for(int i = 1; i <= n; i++) ans += vx[i].key; printf("%d\n", ans); } return 0; }
HDU 1102 Constructing Roads, Prim+优先队列,布布扣,bubuko.com
HDU 1102 Constructing Roads, Prim+优先队列
原文地址:http://blog.csdn.net/u011439796/article/details/38295969