zoj3946Highway Project

xiaoxiao2021-02-28  30

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 Tindicating 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).

<h4< dd=""> 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.

<h4< dd=""> 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

题意:有n个点,m条边,接下来有m行,每行四个整数a,b,c,d表示a,b之间建一条路时间为c,花费为d,让你输出最少的时间以及花费,如果时间相等输出最少的花费;

思路:简单的最短路问题,可以用dijstra写,因为dijstra更新的时候是找经过当前的点可以使路径更短,但是现在有相等的情况,所以更新的时候应该找经过当前的点可以是路径相等或者更短,细节看代码;

#include<stack> #include<queue> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<map> #include<iostream> #include<string.h> #include<algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; const int inf=0x3f3f3f3f; const int MAXN=100005; const int MAXM=10005; struct qnode { int v; int w,c; qnode(int _v=0,int _w=0,int _c=0):v(_v),w(_w),c(_c){}; bool operator<(const qnode &r) const//定义优先队列 { if(w==r.w)//如果是时间相等,花费少的优先 return c>r.c; return w>r.w; } }; struct Edge//建图 { int v; int w,c; Edge(int _v=0,int _w=0,int _c=0):v(_v),w(_w),c(_c){}; }; vector<Edge>E[MAXN]; ll dis[MAXN]; int book[MAXN]; int n,m; ll ans;//花费 void dij() { mem(book,0); mem(dis,inf); priority_queue<qnode>q; while(!q.empty()) q.pop(); dis[0]=0; q.push(qnode(0,0,0)); qnode tmp; while(!q.empty()) { tmp=q.top(); q.pop(); int u=tmp.v;//根据定义的优先队列,出队的一定是时间最少的,或者是时间相等的情况下,花费最少的 if(book[u]) continue; book[u]=1; ans+=tmp.c; for(int i=0;i<E[u].size();i++) { int v=E[u][i].v; int w=E[u][i].w; int c=E[u][i].c; if(!book[v]&&dis[v]>=dis[u]+w)//更新,一定要写=,这是关键,不然不能计算出时间相等时最小的费用 { dis[v]=dis[u]+w; q.push(qnode(v,dis[v],c)); } } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); int u,v,w,c; for(int i=0;i<=n;i++) E[i].clear(); for(int i=0;i<m;i++) { scanf("%d%d%d%d",&u,&v,&w,&c); E[u].push_back(Edge(v,w,c)); E[v].push_back(Edge(u,w,c)); } ans=0; dij(); ll sum=0; for(int i=0;i<n;i++) sum+=dis[i]; printf("%lld %lld\n",sum,ans); } }

转载请注明原文地址: https://www.6miu.com/read-2603196.html

最新回复(0)