题目链接: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+优先队列
原文:http://www.cnblogs.com/mengfanrong/p/4245082.html