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 ≤ 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 NM (1 ≤ NM ≤ 105).

Then followed by M lines, each line contains four integers XiYiDiCi (0 ≤ XiYi < N, 0 < DiCi < 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 个顶点,编号0到n-1,给出m条边,每条边有对应的长度和花费,在保证从顶点0到其他所有的顶点的最小距离不变的情况下,要求花费最小,求到达所有顶点的最小距离的和以及最小花费的和


题解:

昨天的浙江省省赛题,做的是场外同步赛,渣渣队伍只做了五道题,其中这一道题刚做过原题啊,虽然改变了一点点,瞬间怀疑人生了.........

就这一道几乎是原题了,还错了好几次......

原题题解,当时做的直接跑了和裸的dijkstra,连数据范围都没注意看,直接TLE了.....
后来一怒之下改成spfa,然后跑了wa,瞬间纠结了,难道学了这么久,遇到个最短路而且还是原题都搞不出来?

实在找不到问题了,才注意到,是不是超int了......然后把所有的变量都改成了long long 型(循环变量都没放过!),终于AC了...

题目几乎没变,就是裸的SPFA 多加个属性限制,个人觉得学算法主要是学某些巧妙的思路,只有真正理解了,才可能在实际的问题中灵活使用来解决问题,虽然自己并没学多少东西...不过学过的一定要弄明白,否则一知半解的和不知道没多大区别,好吧,加油吧!


ps:

另外一个思路是:在原图里跑出最短路,然后新建最短路的图,在其中跑一下最小树形图(好像是这样),确实能做,但是个人感觉好复杂,这道题其实就是最短路多加了一个属性,甚至可以多加n个属性,让你保证这n个属性一级一级的满足,求最优解,这样的话,用最短路也还是可以做的,只是多开几个数组,多加几级判断,但是用这样跑两个算法的就不一定了,也就是说可移植性不强,只是为了做一道题,不是一类题....(渣渣分析,大神勿喷)


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const ll maxn=100005;
ll edgenum,vis[maxn],head[maxn],dist[maxn],cost[maxn];
struct node
{
	ll from,to,len,val;
	ll next;
}edge[maxn*5];
void init()
{
	edgenum=0;
	memset(head,-1,sizeof(head));
	memset(dist,inf,sizeof(dist));
	memset(vis,0,sizeof(vis));
	memset(cost,inf,sizeof(cost));
}
void add(ll u,ll v,ll d,ll c)
{
	node tp={u,v,d,c,head[u]};
	edge[edgenum]=tp;
	head[u]=edgenum++;
}
void dijkstra(ll n,ll st)
{
	queue<ll> q;
	q.push(st);
	vis[st]=1;
	dist[st]=0;
	while(!q.empty())
	{
		ll v=q.front();q.pop();
		vis[v]=0;
		for(ll i=head[v];i!=-1;i=edge[i].next)
		{
			ll u=edge[i].to;
			if(dist[edge[i].to]>dist[v]+edge[i].len)
			{
				dist[edge[i].to]=dist[v]+edge[i].len;
				cost[edge[i].to]=edge[i].val;
				if(!vis[edge[i].to])
				{
					vis[edge[i].to]=1;
					q.push(edge[i].to);
				}
			}
			else if(dist[edge[i].to]==dist[v]+edge[i].len&&edge[i].val<cost[edge[i].to])//这相当于是二级最短路的判断了吧
			{
				cost[edge[i].to]=edge[i].val;//虽然更新了花费,但是最短路没有发生变化,所以这样的顶点不需要再次入队(虽然入队不影响结果)
			}
		}
	}
}
int main()
{
	//freopen("shuju.txt","r",stdin);
	ll t;
	scanf("%lld",&t);
	while(t--)
	{
		ll n,m;
		scanf("%lld%lld",&n,&m);
		init();
		for(ll i=0;i<m;++i)
		{
			ll u,v,d,c;
			scanf("%lld%lld%lld%lld",&u,&v,&d,&c);
			add(u,v,d,c);add(v,u,d,c);
		}
		ll minlenth=0,mincost=0;
		dijkstra(n,0);
		for(ll i=1;i<n;++i)
		{
			minlenth+=dist[i];
			mincost+=cost[i];
		}
		printf("%lld %lld\n",minlenth,mincost);
	}	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值