zoj-3946-Highway Project【13th浙江省赛】【最短路】
2016-04-23 23:25
387 查看
3946-Highway Project
Time Limit: 2 Seconds Memory Limit: 65536 KB
Edward, the emperor of the Marjar Empire, wants to build some bidirectional highways so that he can reach other cities from the capital as fast as possible. Thus, he proposed the highway project.
The Marjar Empire has N cities (including the capital), indexed from 0 to N - 1 (the capital is 0) and there are M highways can be built. Building the i-th highway costs Ci dollars. It takes Di minutes to travel between city Xi and Yi on the i-th highway.
Edward wants to find a construction plan with minimal total time needed to reach other cities from the capital, i.e. the sum of minimal time needed to travel from the capital to city i (1 ≤ i ≤ N). Among all feasible plans, Edward wants to select the plan with minimal cost. Please help him to finish this task.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first contains two integers N, M (1 ≤ N, M ≤ 105).
Then followed by M lines, each line contains four integers Xi, Yi, Di, Ci (0 ≤ Xi, Yi < N, 0 < Di, Ci < 105).
Output
For each test case, output two integers indicating the minimal total time and the minimal cost for the highway project when the total time is minimized.
Sample Input
2
4 5
0 3 1 1
0 1 1 1
0 2 10 10
2 1 1 1
2 3 1 2
4 5
0 3 1 1
0 1 1 1
0 2 10 10
2 1 2 1
2 3 1 2
Sample Output
4 3
4 4
题目链接:ZOJ-3946
题目大意:有n个城市,m条道路可选维修,给出m条道路分别需要花费的钱和时间。保证时间最小的情况下,再保证钱最少,问从0点到其余点最少时间和花费多少。
题目思路:模板题,最短路,套用Dijkstra。权值 = 时间*10^6 + 钱。这样,保证时间最少(比重大),并细调保证了钱最少。
模板上需要稍加修改的地方是:更新到达该点的权值时,将前面路的零头(即维修路的花费)省去,因为道路只需要维修一次,补省去会重复计算。
注意inf的要大。
以下是代码:
// // AK.cpp // ZOJ // // Created by pro on 16/4/23. // Copyright (c) 2016年 pro. All rights reserved. // #include <iostream> #include <cmath> #include <cstring> #include <string> #include <cstdio> #include <vector> #include <algorithm> #include<map> #include <queue> using namespace std; const int MAXN=100005; #define INF 0xffffffffffffffff #define SSS 1000000 #define ll unsigned long long struct qnode { int v; ll c; qnode(int _v=0,ll _c=0):v(_v),c(_c){} bool operator< (const qnode &r)const { return c>r.c; } }; struct Edge { int v; ll cost; Edge(int _v=0,ll _cost=0):v(_v),cost(_cost){} }; vector< Edge> E[MAXN]; bool vis[MAXN]; ll dist[MAXN]; void Dijkstra(int n,int start)//点的编号从1开始 { memset(vis,false, sizeof(vis)); for(int i=1;i<=n;i++)dist[i]=INF; priority_queue<qnode> que; while(!que.empty())que.pop(); dist[start]= 0; que.push(qnode(start,0)); qnode tmp; while(!que.empty()) { tmp=que.top(); que.pop(); int u=tmp.v; if(vis[u]) continue; vis[u]= true; for(int i = 0;i < E[u].size();i++) { int v=E[tmp.v][i].v; ll cost = E[u][i].cost; ll dist_u = dist[u] / SSS * SSS; if(!vis[v] && dist[v] > dist_u+cost) { dist[v] = dist_u + cost; que.push(qnode(v, dist[v])); } } } } void addedge(int u,int v,ll w) { E[u].push_back(Edge(v ,w)); } int main() { int t; cin >> t; while(t--) { for (int i = 0; i < MAXN; i++) E[i].clear(); int n,m; scanf("%d%d",&n,&m); for (int i = 0; i < m; i++) { int u,v,b; ll w; cin >> u >> v >> w >> b; w = w * SSS + b; //处理权值 addedge(u + 1, v + 1, w); //注意从1开始 addedge(v + 1, u + 1, w); } Dijkstra(n,1); ll ans1 = 0,ans2 = 0; for (int i = 2; i <= n; i++) { ans1 += dist[i] / SSS; ans2 += dist[i] % SSS; } cout << ans1 << " " << ans2 << endl; } return 0; }
相关文章推荐
- [算法练习]找出40000以内的素数
- ubuntu 软件安装和配置
- opencv2.4.9在visual studio 2013中的配置
- LeetCode 345. Reverse Vowels of a String
- scala学习
- 你不知道的JavaScript上卷笔记
- VMware 10激活码
- ZOJ 3944 People Counting
- Struts2连接数据库实现登陆(验证码)、注册
- 标签传递算法
- thinkphp自带验证码出错
- 2016腾讯实习生暑期招聘
- java之通过反射,来获得某对象的所有方法(类方法提取器)
- android studio之build.gradle写法简介
- Noip2012普及组
- 有助人生名人名言100句
- Java方法总结与源码解析(未完待续)
- php 图片添加文字水印 以及 图片合成(微信快码传播)
- Struts1运用Java注解实现简单的权限控制
- 插入排序