zoj--3946--Highway Project(SPFA)

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 ≤ iN). 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

题意:给出n个城市还有m条路,每条路都有一定的花费,建成之后跑起来也需要一定的时间,0是首都,现在要求0到每一个城市的距离都最短,输出花费,并且求出在最短距离下的花费有多少

思路:只是一个很简单的SPFA而已,因为点有点多,map存不下,所以地杰斯特拉肯定是不可以的,做这个题的时候没想到怎么存放花费,其实就是以时间为主要条件,然后花费作为第二个条件,dis[i]表示到达城市i的最短距离,cost[i]表示到达i所需要的最少花费的边,因为求dis的时候已经把树建好了,所以cost不需要考虑建树的问题,直接求最小就行

数据有点大,最好用long long

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 200000+100
#define INF 0x3f3f3f3f
#define ll long long 
struct node
{
	ll u,v,time,cost;
	ll next;
}edge[MAXN*10];
ll cnt,n,m,vis[MAXN],head[MAXN],dis[MAXN],cost[MAXN];
void add(ll u,ll v,ll time,ll len)
{
	node E={u,v,time,len,head[u]};
	edge[cnt]=E;
	head[u]=cnt++;
}
void SPFA()
{
	memset(vis,0,sizeof(vis));
	memset(dis,INF,sizeof(dis));
	memset(cost,INF,sizeof(cost));
	queue<ll>q;
	vis[0]=1;
	dis[0]=0;
	q.push(0);
	while(!q.empty())
	{
		ll u=q.front();
		q.pop();
		vis[u]=0;
		for(ll i=head[u];i!=-1;i=edge[i].next)
		{
			node E=edge[i];
			if(dis[E.v]>dis[E.u]+E.time)
			{
				dis[E.v]=dis[E.u]+E.time;
				cost[E.v]=E.cost;
				if(!vis[E.v])
				{
					vis[E.v]=1;
					q.push(E.v);
				}
			}
			if(dis[E.v]==dis[E.u]+E.time&&cost[E.v]>E.cost)
			{
				cost[E.v]=E.cost;
			}
		}
	}
}
int main()
{
	ll t;
	scanf("%lld",&t);
	while(t--)
	{
		scanf("%lld%lld",&n,&m);
		cnt=0;
		memset(head,-1,sizeof(head));
		ll u,v,time,len;
		for(ll i=0;i<m;i++)
		{
			scanf("%lld%lld%lld%lld",&u,&v,&time,&len);
			add(u,v,time,len);
			add(v,u,time,len);
		}
		SPFA();
		long long sdis=0,scost=0;
		for(ll i=1;i<n;i++)
		{
			sdis+=dis[i];
			scost+=cost[i];
		}
		printf("%lld %lld\n",sdis,scost);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值