[caioj 1091] 最小生成树2---prim
来源:互联网 发布:尼康d800调焦软件 编辑:程序博客网 时间:2024/06/05 11:55
【题目描述】
大家还记得“西南旱灾”吗?我们有多少同胞没有水喝?“干净的水”对他们来说也是种奢望!当大家还在浪费水,洗澡还花上10几分钟,有没有觉得羞愧?西南地区的同胞生活在水深火热之中,yuyan的工程队特意赶到灾区挖井,以缓解旱情。
根据调查,工程队发现有N个地方缺水十分严重!工程队决定在这N个地方选择一些地方挖井,然后在某两个地方之间建立一条运输管道,通过管道把井水传输到其他地方,最后使这N个地方都有水供应!可是,因为地形的差异,每个地方挖水井所要付出的成本是不一定相同的!每两个地方之间建立管道所需要付出的成本也不一定相同。
现在,工程队估算出了每个地方挖井所需要的成本,每两个地方建立运输管道的成本。希望你能告诉他们:在哪些地方挖井,在哪些地方之间建立管道,才能使的总成本最小?同为炎黄子孙,为了广大的受苦同胞,作为中华儿女的你们,有责任去完成这个任务!
【输入格式】
一个整数N(1≤N≤300)表示N个地方严重缺水
以下N行,每行一个数,第I行的数为COSTi,表示在编号为i的地方挖水井所需的成本为COSTi
再接着N行,每行N个数,第I行第J个数X
表示在编号为I和编号J之间建造一条管道需要的成本是X
这个N*N的矩阵满足A[I,J]=A[J,I] A[I,I]=0
【输出格式】
一个整数,表示使得N个地方都有水的最小成本。
【样例输入】
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
【样例输出】
9
【数据约定】
对于20%的数据:N≤10
对于60%的数据:N≤100
对于100%的数据:N≤300, 所有成本≤100000
Hint:在编号为4的地方挖口井,成本为3
在1,2之间建一条管道,成本为2
在1,3之间建一条管道,成本为2
在1,4之间建一条管道,成本为2
至此,这4个地方都直接或间接有水供应,最小成本为3+2+2+2=9
分析
初看可能会想到枚举水井暴力一下,但总觉得不对.~~但细想一下,既然只有两道最小生成树的题且上题是kruskal,那么这题就用prim吧.~~So,利用prim的思想,对贪心的策略稍加修改就行了(最小生成树本就是贪心)
修改:
1.选挖井成本最小的作为起点
2.取min(修管道成本,挖井成本)更新dis
代码
#include <cstdio>#include <cstdlib>#include <cstring>#include <queue>#define open(s) freopen(s".in","r",stdin); freopen(s".out","w",stdout);#define close fclose(stdin); fclose(stdout);using namespace std;struct node{ int p; int d; bool operator < (const node &b) const { return d>b.d; }};int n;int mp[305][305];int w[305];inline int read() //读优{ int k=1; int sum=0; char c=getchar(); for(;'0'>c || c>'9' ;c=getchar()) if(c=='-') k=-1; for(;'0'<=c && c<='9';c=getchar()) sum=sum*10+c-'0'; return sum*k;}inline void write(int x) // 输优{ if(x<0) { putchar('-'); x*=-1; } if(x>9) write(x/10); putchar(x%10+'0');}inline int min(int x,int y){ return x<y?x:y;}inline void prim(int p){ int ans=0; bool vis[305]={0}; int dis[305]={0}; priority_queue<node>q; //优先队列 优化 memset(dis,0x3f,sizeof(dis)); dis[p]=w[p]; q.push((node){p,w[p]}); int T=n; for(int t=1;t && T;) { p=q.top().p; q.pop(); --t; if(vis[p]) continue ; ans+=dis[p]; vis[p]=1; --T; for(int i=1;i<=n;++i) if(!vis[i] && min(mp[p][i],w[i])<dis[i]) { ++t; dis[i]=min(mp[p][i],w[i]); //取修管道\挖井中成本最小的 q.push((node){i,dis[i]}); } } write(ans);}int main(){ open("1091"); n=read(); int p=1; for(int i=1;i<=n;++i) { w[i]=read(); if(w[i]<w[p]) p=i;} //找起点 for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) mp[i][j]=read(); prim(p); close; return 0;}
- [caioj 1091] 最小生成树2---prim
- Prim最小生成树
- 最小生成树 prim
- 最小生成树 Prim
- 最小生成树-Prim
- Prim最小生成树
- 最小生成树 Prim
- prim最小生成树
- 最小生成树prim
- 最小生成树 prim
- prim 最小生成树
- Prim 最小生成树
- 最小生成树---Prim
- 最小生成树-prim
- 最小生成树---Prim
- 最小生成树(Prim)
- 最小生成树 -PRIM
- 最小生成树--PRIM
- web开发网
- 汇编语言实现倒序输出
- 基于live555实现的RTSPServer对底层进行性能优化的方法
- 两个栈实现一个队列-思路
- echarts报表展示
- [caioj 1091] 最小生成树2---prim
- Servlet入门
- linux(ubuntu)环境下安装IDEA
- MongoDB笔记三:C Driver 含日期类型字段document添加和查询,指定document返回的field
- live555二次开发经验总结:RTSPClient客户端与RTSPServer服务器
- 汇编语言实现冒泡算法
- leetcode-14-Longest Common Prefix
- UML图中的依赖、关联、继承、实现、聚合、组合关系的学习
- 面试题Getmemory