HDU 1102 Constructing Roads, Prim+优先队列
题目链接:HDU 1102 Constructing Roads
Constructing Roads
C such that there is a road between A and C, and C and B are connected.
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.
i and village j.
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.
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+优先队列的更多相关文章
- HDU 1102(Constructing Roads)(最小生成树之prim算法)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Ja ...
- hdu 1102 Constructing Roads (Prim算法)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...
- hdu 1102 Constructing Roads (最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...
- HDU 1102 Constructing Roads (最小生成树)
最小生成树模板(嗯……在kuangbin模板里面抄的……) 最小生成树(prim) /** Prim求MST * 耗费矩阵cost[][],标号从0开始,0~n-1 * 返回最小生成树的权值,返回-1 ...
- hdu 1102 Constructing Roads Kruscal
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:这道题实际上和hdu 1242 Rescue 非常相似,改变了输入方式之后, 本题实际上更 ...
- HDU 1102 Constructing Roads
Constructing Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDU 1102 Constructing Roads(kruskal)
Constructing Roads There are N villages, which are numbered from 1 to N, and you should build some r ...
- hdu 1102 Constructing Roads(最小生成树 Prim)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Problem Description There are N villages, which ...
- hdu 1102 Constructing Roads(kruskal || prim)
求最小生成树.有一点点的变化,就是有的边已经给出来了.所以,最小生成树里面必须有这些边,kruskal和prim算法都能够,prim更简单一些.有一点须要注意,用克鲁斯卡尔算法的时候须要将已经存在的边 ...
随机推荐
- [ACM] poj 3468 A Simple Problem with Integers(段树,为段更新,懒惰的标志)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 55273 ...
- Cocos2d-x 3.0final 终结者系列教程01-无论是从cocos2d-x2.x升级到版本cocos2d-x3.x
诡谲的江湖,易变. 花花世界,车来人往. 最终确定.安家,将Cocos2d-x3.0final相关技术精加工的版本.并推出了博客文章, 不为他人,只为自己. 学习交流QQ群:301954471 --- ...
- [LeetCode290]Word Pattern
题目: Given a pattern and a string str, find if str follows the same pattern. Here follow means a full ...
- HDU 3126 Nova [2009 Asia Wuhan Regional Contest Online]
标题效果 有着n巫妖.m精灵.k木.他们都有自己的位置坐标表示.冷却时间,树有覆盖范围. 假设某个巫妖攻击精灵的路线(他俩之间的连线)经过树的覆盖范围,表示精灵被树挡住巫妖攻击不到.求巫妖杀死所有精灵 ...
- Redis实现分布式锁与任务队列
Redis实现分布式锁 与 实现任务队列 这一次总结和分享用Redis实现分布式锁 与 实现任务队列 这两大强大的功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说 ...
- 寒假了,想深入学习c++
本来在图书馆借了好几本属,但是,自己没有经验,借的书都太深奥,看不懂,哎,桑心!
- SQL Server 2008 R2 跟踪标志
原文:SQL Server 2008 R2 跟踪标志 跟踪标志用于临时设置特定服务器的特征或关闭特定行为.例如,如果启动 SQL Server 的一个实例时设置了跟踪标志 3205,将禁用磁带机的硬件 ...
- 在内存中建立 MySQL 的临时目录(转)
MySQL 系统会在内存(MEMORY)和磁盘(MyISAM)中建立临时表,如何能知道在磁盘中建立了多少临时表以及在内存中建立多少临时表呢?你可以通过下面命令获知: ? 1 2 3 4 5 6 7 m ...
- Binary Tree Inorder Traversal(转)
Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tr ...
- RandomAccessFile实时读取大文件(转)
最近有一个银行数据漂白系统,要求操作人员在页面调用远端Linux服务器的shell,并将shell输出的信息保存到一个日志文件,前台页面要实时显示日志文件的内容.这个问题难点在于如何判断哪些数据是新增 ...