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;
}

转载于:https://www.cnblogs.com/01world/p/5651222.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值