ZJOJ Highway Project 3946(单源最短路+贪心)

来源:互联网 发布:淘宝删除邀请我的回答 编辑:程序博客网 时间:2024/06/14 14:58

大意:有n,m表示n个点,m个边,然后就是m条边的信息,分别是x,y,ti,cost.点xy间的路耗费时间是ti,金钱是cost.因为点和边范围为10^5,所以想到复杂度小的SPFA(O(E)).

思路:直接是SPFA边求最短的时间的路,同时求耗费的金钱。但是注意耗费的金钱,cost[]数组不能够存从源点到当前点的耗费,因为若
两条路径时间是相等的,但是一条路是好多节点组成的但是耗费多。但是另一个是节点少耗费少。肯定选节点少的路径。

#include<map>#include<queue>#include<cmath>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define ll long long#define LL __int64#define inf 0x3f3f3f3f#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;struct node{    ll to,next,ti,cost;}q[100010*5];ll head[100010*5],cnt,dis[100010],cost[100010],n;bool vis[100010];void bu(ll a,ll b,ll c,ll d){    q[cnt].to = b;    q[cnt].ti = c;    q[cnt].cost = d;    q[cnt].next = head[a];    head[a] = cnt++;}void SPFA(){    memset(vis,false,sizeof(vis));    memset(dis,inf,sizeof(dis));    memset(cost,inf,sizeof(cost));    queue<ll>que;    while(!que.empty())        que.pop();    dis[0] = cost[0] = 0;    vis[0] = true;    que.push(0);    while(!que.empty()){        ll u = que.front();        vis[u] = false;        que.pop();        for( int i = head[u];~i;i = q[i].next ){            int v = q[i].to;            if( (dis[v] > dis[u] + q[i].ti)||(dis[v] == dis[u] + q[i].ti&&cost[v] > q[i].cost)){                dis[v] = dis[u] + q[i].ti;                cost[v] = q[i].cost;                if(!vis[v]){                    vis[v] = true;                    que.push(v);                }            }        }    }    ll ans1,ans2;    ans1=ans2=0;    for(ll i = 0;i < n ;++ i){        ans1 += dis[i];        ans2 += cost[i];    }    printf("%lld %lld\n",ans1,ans2);}int main(){    ll m,i,j,k,cla,a,b,c,d;    scanf("%lld",&cla);    while(cla--){        memset(head,-1,sizeof(head));        cnt = 0;        scanf("%lld%lld",&n,&m);        for(i = 0;i <m;++ i){            scanf("%lld%lld%lld%lld",&a,&b,&c,&d);            bu(a,b,c,d);bu(b,a,c,d);        }        SPFA();    }    return 0;}
0 0
原创粉丝点击