题目链接:HDU 1102 Constructing Roads

Constructing Roads

Problem Description
There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village
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.
 
Input
The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village
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.
 
Output
You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum. 
 
Sample Input
3
0 990 692
990 0 179
692 179 0
1
1 2
 
Sample Output
179
 
Source
 
Recommend
Eddy   |   We have carefully selected several similar problems for you:  1142 1598 1116 1269 1596 
 
题意

有N个村子要修道路,给出了修每条道路的原始费用,如今有的道路已经修好了。我们要求的是修剩下的道路的最小费用。

分析

最小生成树算法,由于是邻接矩阵,因而使用Prim方法很方便求解,对于已经修好的道路,我们能够将他们的费用设置为0,再用Prim算法求解就可以得到。

代码

邻接矩阵:
#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+优先队列的更多相关文章

  1. HDU 1102(Constructing Roads)(最小生成树之prim算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Ja ...

  2. hdu 1102 Constructing Roads (Prim算法)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...

  3. hdu 1102 Constructing Roads (最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...

  4. HDU 1102 Constructing Roads (最小生成树)

    最小生成树模板(嗯……在kuangbin模板里面抄的……) 最小生成树(prim) /** Prim求MST * 耗费矩阵cost[][],标号从0开始,0~n-1 * 返回最小生成树的权值,返回-1 ...

  5. hdu 1102 Constructing Roads Kruscal

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:这道题实际上和hdu 1242 Rescue 非常相似,改变了输入方式之后, 本题实际上更 ...

  6. HDU 1102 Constructing Roads

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  7. HDU 1102 Constructing Roads(kruskal)

    Constructing Roads There are N villages, which are numbered from 1 to N, and you should build some r ...

  8. hdu 1102 Constructing Roads(最小生成树 Prim)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Problem Description There are N villages, which ...

  9. hdu 1102 Constructing Roads(kruskal || prim)

    求最小生成树.有一点点的变化,就是有的边已经给出来了.所以,最小生成树里面必须有这些边,kruskal和prim算法都能够,prim更简单一些.有一点须要注意,用克鲁斯卡尔算法的时候须要将已经存在的边 ...

随机推荐

  1. Cocos2d-x场景变化相关功能介绍

    现场由导演级交换机Director实现.之间的相关的功能,如下面: runWithScene(Scene* scene).该函数能够执行场景.仅仅能在启动第一个场景时候调用该函数.假设已经有一个场景执 ...

  2. Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)(转)

    互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...

  3. hdu3572 任务分配/最大流量推论全流

    意甲冠军:将n分配的任务m机.到的每个任务需要的天数(如果没有持续的日常),并能做到在哪些天任务.询问是否有计划. 典型的任务(X)----日(Y)一半的最大流量,(因为这个任务是天之间的关系)处理器 ...

  4. Connect2015 简要整理

    2015 简要整理 去年 Connect(); 2014 Visual Studio Contact(); 直播笔记 对于我个人来说,今年 Connect(); 的三个重要发布: ASP.NET 5 ...

  5. 兔子--Spring基金会

    设计模式的基本目的: 对象之间的解耦.使用容器来管理组件.减少不同组件之间的耦合 控制返回,搜索请求委托给容器 将积极考虑被动接受 版权声明:本文博主原创文章,博客,未经同意不得转载.

  6. 第四章——SQLServer2008-2012资源及性能监控(1)

    原文:第四章--SQLServer2008-2012资源及性能监控(1) 性能优化的第一步是发现问题,而发现问题通常又有两类:突发问题的侦测和常规问题的侦测,对于常规问题的侦测,通常需要有一个长效的性 ...

  7. directX--大约CSource和CSourceStream (谁在叫fillbuffer)

    CSourceStream类别,它是CSource类别OutputPin[source.h/source.cpp] 派生自CAMThread和CBaseOutputPinl         成员变量: ...

  8. Git协作流程(转)

    Git 作为一个源码管理系统,不可避免涉及到多人协作. 协作必须有一个规范的流程,让大家有效地合作,使得项目井井有条地发展下去."协作流程"在英语里,叫做"workflo ...

  9. 阿里云ECSserver部署django

    highlight=uwsgi%20django">參考 server安装的是Centos 系统. uwsgi是使用pip安装的. nginx是使用yum install nginx安 ...

  10. Install shipyard

    2台机器,192.168.1.153,192.168.1.154 安装Shipyard 1. 154作为集群主节点,在154机器上执行命令 curl -sSL https://shipyard-pro ...