ZOJ 3946(單源最短路)

//題意:給定n個點,m條路,每條路的花費爲d,消耗的時間爲c
//     求從起點到各個點的時間之和最小且花費最小
//方法:spfa跑一遍並維護cost   答案會爆int  有點坑
#include <iostream>
#include <string.h>
#include <queue>
#include <climits>
#define error 999999999
using namespace std;
int fir[100100], vis[100100];
long long dis[100100], cost[100100];
long long ans, sum;
int cnt;
queue <int> que;
struct node {
    int to, next, v, c;
}edge[200010];

void add(int a, int b, int c, int d)
{
    edge[cnt].to = b;
    edge[cnt].v = c;
    edge[cnt].c = d;
    edge[cnt].next = fir[a];
    fir[a] = cnt++;
}

void spfa(int op, int n)
{
    
    for(int i = 0; i <= n; i++)
    {
        vis[i] = 0;
        dis[i] = LONG_LONG_MAX;
        cost[i] = LONG_LONG_MAX;
    }
    que.push(op);
    vis[op] = 1;
    cost[op] = 0;
    dis[op] = 0;
    while(!que.empty())
    {
        int now = que.front();
        que.pop();
        vis[now] = 0;
        for(int i = fir[now]; i != -1; i = edge[i].next)
        {
            int to = edge[i].to, val = edge[i].v;
            if(dis[now] + val < dis[to]){
                dis[to] = dis[now] + val;
                cost[to] = edge[i].c;
                if(!vis[to]){
                    vis[to] = 1;
                    que.push(to);
                }
            }
            else if(dis[now] + val == dis[to]){
                if(cost[to] > edge[i].c)
                {
                    cost[to] = edge[i].c;
                    if(!vis[to]){
                        vis[to] = 1;
                        que.push(to);
                    }
                }
            }
        }
    }
    sum = ans = 0;
    for(int i = 0; i < n; i++)
    {
        sum += dis[i];
        ans += cost[i];
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(fir, -1, sizeof fir);
        cnt = 0;
        int n, m, a, b, c, d;
        cin>>n>>m;
        for(int i = 0; i < m; i++)
        {
            cin>>a>>b>>c>>d;
            add(a, b, c, d);
            add(b, a, c, d);
        }
        spfa(0,n);
        cout<<sum<<' '<<ans<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章