您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: