题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5718
题意:
有n个点 m(n,m<=10^5)条路,现在要建路,每条路连接uv两个点,所需时间是time花费是cost,现要求从0点到达其他点的,让时间和最小,当有多种选择时要求修路的总花费最小,输出最小时间及花费;
可以看成最短路问题
我们定义两个数组Time[i]表示从起点到 i 点所需的最小时间,Cost[i]表示到达 i 的那个点 u 到 i 的最小花费;其实就相当于是最短路中的dist和最小生成树中的dist
需要注意的是,本题数据超int了,所以初始化的时候要注意最大值的值;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> #include<vector> using namespace std; #define N 100050 typedef long long LL; const LL INF = (1ll<<60)-1; struct node { int v; LL cost, time; node(int v0=0, LL c=0, LL t=0) : v(v0),cost(c), time(t){} }; vector<vector<node> >G; int n, vis[N]; LL Cost[N], Time[N]; void SPFA() { for(int i=0; i<n; i++) { Cost[i] = Time[i] = INF; vis[i] = 0; } Cost[0] = Time[0] = 0; queue<int>Q; Q.push(0); while(Q.size()) { int p = Q.front(); Q.pop(); vis[p] = 0; int len = G[p].size(); for(int i=0; i<len; i++) { node q = G[p][i]; if(Time[q.v] > Time[p]+q.time || (Time[q.v]==Time[p]+q.time&&Cost[q.v]>q.cost)) { Time[q.v] = Time[p]+q.time; Cost[q.v] = q.cost; if(!vis[q.v]) { vis[q.v] = 1; Q.push(q.v); } } } } LL TimeSum = 0, CostSum = 0; for(int i=1; i<n; i++) { TimeSum += Time[i]; CostSum += Cost[i]; } printf("%lld %lld ", TimeSum, CostSum); } int main() { int T, m; //cout<<INF; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); G.clear(); G.resize(n+2); for(int i=0; i<m; i++) { int u, v; LL cost, time; scanf("%d %d %lld %lld", &u, &v, &time, &cost); G[u].push_back(node(v, cost, time)); G[v].push_back(node(u, cost, time)); } SPFA(); } return 0; }