ZOJ 3946 Highway Project
2016-04-29 08:41
239 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3946
题意:有n个点(编号0~n-1),m条边的一个图,每条边都有权值和搭建这条边所需要的花费。现在从0号点出发,要使得它到其余点的路径和最小,而且在路径和最小的情况下,要求搭建边的花费最少。
思路:首先考虑一个点到其余点最短,可以用dijkstra+堆优化来解决。其次是搭建边的花费,最终构建的图肯定是一个生成树,所以每个点在最短路更新答案的时候只需要记录树连接当前点的那条边的花费即可。比如0到3直接连接权值是10,花费是3。那么[3]就是记录3,然后发现借助2号点去到达3号点更快。并且2-3的那条路花费是5,所以[3]就被更新为5,因为2已经是更新好的点了,而且[2]会记录0-2的边花费。所以最后只需要把[2]~
加一遍就是最终花费。
题意:有n个点(编号0~n-1),m条边的一个图,每条边都有权值和搭建这条边所需要的花费。现在从0号点出发,要使得它到其余点的路径和最小,而且在路径和最小的情况下,要求搭建边的花费最少。
思路:首先考虑一个点到其余点最短,可以用dijkstra+堆优化来解决。其次是搭建边的花费,最终构建的图肯定是一个生成树,所以每个点在最短路更新答案的时候只需要记录树连接当前点的那条边的花费即可。比如0到3直接连接权值是10,花费是3。那么[3]就是记录3,然后发现借助2号点去到达3号点更快。并且2-3的那条路花费是5,所以[3]就被更新为5,因为2已经是更新好的点了,而且[2]会记录0-2的边花费。所以最后只需要把[2]~
加一遍就是最终花费。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <cstdlib> #include <iostream> #include <algorithm> #include <stack> #include <map> #include <set> #include <vector> #include <sstream> #include <queue> #include <utility> using namespace std; #define rep(i,j,k) for (int i=j;i<=k;i++) #define Rrep(i,j,k) for (int i=j;i>=k;i--) #define Clean(x,y) memset(x,y,sizeof(x)) #define LL long long #define ULL unsigned long long #define inf 0x7fffffff #define mod %100000007 const int maxn = 100009; int T,n,m; vector<int> pos[maxn]; vector<int> t[maxn]; vector<int> w[maxn]; LL dis[maxn]; bool flag[maxn]; int money[maxn]; typedef pair<LL,int>Pair; LL dijkstra(int start) { for (int i=1;i<=n;i++) dis[i]=(LL)maxn*maxn; memset(flag,0,sizeof(flag)); dis[start]=0; priority_queue< Pair,vector<Pair>,greater<Pair> >q; q.push(make_pair(dis[start],start)); while (!q.empty()) { Pair top=q.top(); q.pop(); int now=top.second; if (flag[now]) continue; flag[now]=true; for (int j=0;j<(int)pos[now].size();j++) if ((!flag[ pos[now][j] ])&&( t[now][j]+dis[now] <= dis[pos[now][j]] ) ) { if ( t[now][j]+dis[now] == dis[pos[now][j]] ) //权值相同的情况下,取花费最小 money[ pos[now][j] ] = min(w[now][j],money[ pos[now][j] ]) ; else money[ pos[now][j] ] = w[now][j]; //否则就取当前权值最小的花费 dis[pos[now][j]]=dis[now]+t[now][j]; q.push(make_pair(dis[pos[now][j]],pos[now][j])); } } LL ans = 0; rep(i,2,n) ans+=dis[i]; return ans; } void init(int n) { Clean(money,0x3f); rep(i,1,n) { pos[i].clear(); t[i].clear(); w[i].clear(); } } int main() { scanf("%d",&T); int x,y,d,c; while(T--) { scanf("%d %d",&n,&m); init(n); rep(i,1,m) { scanf("%d%d%d%d",&x,&y,&d,&c); x++,y++; pos[x].push_back(y); pos[y].push_back(x); t[x].push_back(d); t[y].push_back(d); w[x].push_back(c); w[y].push_back(c); } LL ans = 0; LL x = dijkstra(1); rep(i,2,n) ans+=money[i]; printf("%lld %lld\n",x,ans); } return 0; }
相关文章推荐
- ScrollView嵌套ListView 在某些机型报空指针问题
- 30岁后程序员的出路[转]
- 漫谈程序员(十三)健康程序猿系列之男人晚睡的7大危害
- Bootstrap模态对话框的简单使用
- 漫谈程序员(十三)健康程序猿系列之男人晚睡的7大危害
- 构建之法阅读笔记05
- ArrayList类详解
- bzoj 4547: Hdu5171 小奇的集合
- Intent过滤器
- svn提交文件时,过滤文件
- (转载收藏)美林投资时钟理论
- 【BZOJ1060】【codevs1435】时态同步,我可以叫它树形递推吗
- 模拟长按
- 常用类
- java初学者:构造方法 技术文章
- 在这个只有20多人的工作空间里,每天还是要多接触一些人的,不然就会被排外
- JDBC(Java Data Base Connectivity)
- navicat进行数据库备份
- 素数求解及其优化
- bzoj 3609: [Heoi2014]人人尽说江南好