浙江省赛zoj3946 Highway Project

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 toN - 1 (the capital is 0) and there are M highways can be built. Building thei-th highway costs Ci dollars. It takes Di minutes to travel between cityXi 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 cityi (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


最近敲代码太不细心了,被自己恶心到了;wa了好几十发,然后一行一行对代码,终于知道我最初的代码错在哪了;

思路对了后代码有三处错误:

1、初始化为无穷大时使用的数太小了,总结经验就是以后都用memset+0x3f初始化为无穷大,一般就能满足条件,自己不用再算极限值;

2、哎,sb了,输入顺序弄反了,题目要求是输入X,Y,D,C,我读入的是X,Y,C,D;为什么不是CD呢,感觉被rou了一道;

3、这个错误算是手误吧,eclipse有个毛病,就是经常出现你按enter换行的时候屏幕显示不刷新,然后看错了,在写"return false"的时候,

      我把"inque[u]=false"的inque[u]="给删了,在前面加了个return,也是没谁了。


题目就是有两个条件限制,第一要求是0点到其他点的距离之和最短,也就是要以先求出最短路为第一优先级;

第二要求就是如果路程一样,要求花费最小;由spfa算法并且记录前继节点,最终得到的图是一课树;也就是说最终是要把所有的点都连接到树上,那么只要在dis[v]==dis[u]+d的时候,选取连接v的消费最小的边(有点像最小生成树算法Prim的思想),就能使路程最短的条件下花费最小。


贴个代码

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<climits>
#include<cmath>
#include<queue>
#define maxn 101000
#define MAX LLONG_MAX/2
#define LL long long
using namespace std;

struct node
{
	int v;
	int c,d;
};
vector<node >head[maxn];
LL dis[maxn];
int outque[maxn];
bool inque[maxn];
int cost[maxn];
bool spfa(int s,int n)
{
	dis[s]=0;
	queue<int>que;
	que.push(s);
	inque[s]=true;
	while(!que.empty())
	{
		int u=que.front();
		que.pop();
		inque[u]=false;
		outque[u]++;
		if(outque[u]>n)
			return false;
		for(int i=0,len=head[u].size();i<len;++i)
		{
			int v=head[u][i].v,c=head[u][i].c,d=head[u][i].d;
			if(dis[v]>dis[u]+d || (dis[v]==dis[u]+d && cost[v]>c))
			{
				dis[v]=dis[u]+d;
				cost[v]=c;
				if(!inque[v])
				{
					que.push(v);
					inque[v]=true;
				}
			}
		}
	}
	LL ans1=0,ans2=0;
	for(int i=1;i<n;++i)
	{
		ans1+=dis[i];
		ans2+=cost[i];
	}
	printf("%lld %lld\n",ans1,ans2);
	return true;
}
int main()
{
	int T;
	while (scanf("%d", &T) != EOF)
	{
		while (T--)
		{
			int n, m;
			scanf("%d%d", &n, &m);
			int u, v, c, d;
			for(int i=0;i<=n;++i)
			{
				head[i].clear();
			}
			for (int i = 0; i < m; ++i)
			{
				scanf("%d%d%d%d", &u, &v, &d, &c);
				head[u].push_back({ v, c, d });
				head[v].push_back({ u, c, d });
			}
			memset(inque, false, sizeof(inque));
			memset(outque, 0, sizeof(outque));
			memset(cost,0x3f,sizeof(cost));
			memset(dis,0x3f,sizeof(dis));
//			for (int i = 0; i <= n; ++i)
//			{
//				cost[i] = INT_MAX;
//				dis[i] = MAX;
//			}
			spfa(0, n);
		}
	}
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值