链接:戳这里
4 4
思路:题目要求输出从首都到各个城市所需要的时间和的最小值
如果最小值有多个,那么输出建设道路话费最小的金额
我们先用spfa跑最短路,并在每次更新最短路的时候贪心去最小的道路花费
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int n,m,tot; struct egde{ int v,d,c,next; }e[500100]; int head[100100],vis[100100]; ll dis[100100],cost[100100]; void init(){ mst(head,-1); tot=0; } void Add(int u,int v,int d,int c){ e[tot].v=v; e[tot].next=head[u]; e[tot].d=d; e[tot].c=c; head[u]=tot++; } void Dijkstra(){ for(int i=0;i<n;i++) dis[i]=INF; for(int i=0;i<n;i++) cost[i]=INF; for(int i=0;i<n;i++) vis[i]=0; queue<int> qu; qu.push(0); dis[0]=0;cost[0]=0; while(!qu.empty()){ int u=qu.front(); qu.pop(); ///if(vis[u]) continue; vis[u]=0; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(dis[v]==dis[u]+e[i].d){ if(cost[v]>e[i].c){ cost[v]=e[i].c; } } if(dis[v]>dis[u]+e[i].d){ dis[v]=dis[u]+e[i].d; cost[v]=e[i].c; if(!vis[v]){ qu.push(v); vis[v]=1; } } } } ll D=0,C=0; for(int i=0;i<n;i++) { ///printf("%lld %lld\n",dis[i],cost[i]); D+=dis[i],C+=cost[i]; } printf("%lld %lld\n",D,C); } int main(){ int T; scanf("%d",&T); while(T--){ init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int u,v,d,c; scanf("%d%d%d%d",&u,&v,&d,&c); Add(u,v,d,c); Add(v,u,d,c); } Dijkstra(); } return 0; }