ZOJ 3946 Highway Project 优先队列dijk
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 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
题意:
要建公路,要求从0点到其他所有点需要的时间之和最小,并且修公路花费最少。
分析:
前情回顾:做比赛的时候根本就没理解题意,我以为是走一遍,求经过的路程最短。后来同学跟我说了题意后,很快就敲出来了,但是无数次WA,因为我把定义的是const int INF=1e17,int,int,int。。。感觉自己蠢到家了!这次错误必须铭记!!!改完后就A了。
思路:每次把可以得到最短距离的点都放了队列中,自定义排序结构就是如果距离相等,那么花费少的优先级高,这样的话,出队的一定是最优的,这样就可以保证花费最少,距离最短了。
在自己无助的时候,搜题解,看到有人是把路程和话费合成一块,这个技巧值得学习!
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
using namespace std;
#define pb push_back
const long long INF=1e17;
typedef long long ll;
const int N=2e5+9;
struct edge
{
int u,v,d,c;
edge(int u,int v,int d,int c):u(u),v(v),d(d),c(c){}
};
struct point
{
ll d;
int u,w;
point(ll a,int b,int c):d(a),u(b),w(c){}
bool operator < (const point& rhs)const{
if(d==rhs.d)return w>rhs.w;
return d>rhs.d;
}
};
ll d[N];
bool vis[N];
int n,m;
vector<edge>edges;
vector<int>g[N];
ll ansx,ansy;
void dijk(int s)
{
priority_queue<point>q;
for(int i=0;i<n;i++)d[i]=INF;
d[s]=0;
memset(vis,0,sizeof(vis));
q.push(point(0,s,0));
while(!q.empty()){
point x=q.top();q.pop();
int u=x.u;
if(vis[u])continue;
vis[u]=1;
ansy+=x.w;
ansx+=x.d;
for(int i=0;i<g[u].size();i++){
edge e=edges[g[u][i]];
if(!vis[e.v]&&d[e.v]>=d[u]+e.d){
d[e.v]=d[u]+e.d;
q.push(point(d[e.v],e.v,e.c));
}
}
}
//for(int i=0;i<n;i++)ansx+=d[i];
}
void addedge(int u,int v,int d,int w)
{
edges.push_back(edge(u,v,d,w));
int t=edges.size();
g[u].pb(t-1);
}
void init()
{
for(int i=0;i<n;i++)g[i].clear();
edges.clear();
ansx=ansy=0;
}
int main()
{
//freopen("f.txt","r",stdin);
int T;scanf("%d",&T);
while(T--){
init();
scanf("%d%d",&n,&m);
int u,v,d,w;
for(int i=0;i<m;i++){
scanf("%d%d%d%d",&u,&v,&d,&w);
addedge(u,v,d,w);
addedge(v,u,d,w);
}
dijk(0);
printf("%lld %lld\n",ansx,ansy);
}
return 0;
}