原题地址:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827370050
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 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,1,2.....n-2,n-1)。
思路:用dijkstra算法求最短路的同时维护一个expend数组,expend[i]表示选择连接城市i的那条路的直接花费,想要
花费最小,在有两条距离相同的路的时候就要选择花费小的那一条,这里存图时城市编号加1了,就相当于城市从1到n了,也可以不加。
代码:
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int TT;scanf("%d",&TT);for(int tt=1;tt<=TT;tt++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define repp(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define perr(i,a,b) for(int i=a;i>b;i--)
#define pb push_back
#define eb push_back
#define fi first
#define se second
#define mst(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const double angcst=PI/180.0;
const ll mod=998244353;
ll max_3(ll a,ll b,ll c){if(a>b&&a>c)return a;if(b>c)return b;return c;}
ll min_3(ll a,ll b,ll c){if(a<b&&a<c)return a;if(b<c)return b;return c;}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qmul(ll a,ll b){ll s=(long double)a/mod*b;s=a*b-s*mod;if(s<0)s+=mod;if(s>=mod)s-=mod;return s;}
template <typename _Tp> inline _Tp read(_Tp&x){
char c11=getchar(),ob=0;x=0;
while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')c11=getchar(),ob=1;
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}
const int maxn=200010;
ll dis[maxn],expend[maxn];
int n,m;
struct node
{
int v;
ll w,cost;
};
vector<node>g[maxn];
void add(int u,int v,ll w,ll cost)
{
g[u].pb((node){v,w,cost});
}
void dijkstra()
{
priority_queue<P,vector<P>,greater<P> >q;
rep(i,1,n)expend[i]=dis[i]=LINF;
dis[1]=0;
q.push(P(dis[1],1));
while(!q.empty())
{
P p=q.top();q.pop();
int u=p.second;
ll d=p.first;
if(dis[u]<d)continue;
for(int i=0;i<g[u].size();i++)
{
ll v=g[u][i].v,w=g[u][i].w,cost=g[u][i].cost;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
expend[v]=cost;
q.push(P(dis[v],v));
}
else if(dis[v]==dis[u]+w)//有两条距离相同的路
expend[v]=min(cost,expend[v]);
}
}
}
int main()
{
int T;read(T);
while(T--)
{
read(n);read(m);
rep(i,1,m)
{
int u,v;ll w,cost;
read(u);read(v);
read(w);read(cost);
add(u+1,v+1,w,cost);
add(v+1,u+1,w,cost);
}
dijkstra();
ll alldis=0,allcost=0;
rep(i,2,n)
{
cout<<expend[i]<<endl;
alldis+=dis[i];
allcost+=expend[i];
}
printf("%lld %lld
",alldis,allcost);
rep(i,1,n)g[i].clear();
}
return 0;
}