1003Emergency(25)

正式入坑 PAT ,这道题我的解是东拼西凑吧,用了 http://blog.csdn.net/apie_czx/article/details/45310675  这个大佬的思路,然后刘汝佳的模板

在此奉上代码


#include<iostream>

#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn=500+5;
const int INF=100000000;
struct E{
    int from,to,weight;
    E(int from,int to,int weight):from(from)
     ,to(to),weight(weight){}
   bool operator <(const E &rhs)const{
       return this->weight>rhs.weight;
    }
 
};
struct H{
    int u,dis;
    H(int u,int dis):
        u(u),dis(dis){}
   bool operator <(const H &rhs) const{
        return this->dis>rhs.dis;
    }
};
vector<int> G[maxn];
vector<E> edges;
int dis[maxn];
int mark[maxn];
int paths[maxn];
int nums[maxn];
int all_nums[maxn];
void addEdge(int from,int to,int weight)
{
    edges.push_back(E(from,to,weight));
    int ss=edges.size();
    G[from].push_back(ss-1);
}
 
int main()
{
#ifdef LOCAL
    freopen("data.in","r",stdin);
#endif
    int n,m,from,to;
    scanf("%d%d%d%d",&n,&m,&from,&to);
        edges.clear();
        for(int i=0;i<n;i++)
        {
            G[i].clear();
            dis[i]=INF;
            mark[i]=0;
            paths[i]=0;
           scanf("%d",&nums[i]);
            all_nums[i]=0;
        }
        int c1,c2,w;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&c1,&c2,&w);
            addEdge(c1,c2,w);
            addEdge(c2,c1,w);
        }
        dis[from]=0;
        paths[from]=1;
        all_nums[from]=nums[from];
        priority_queue<H> qq;
        qq.push(H(from,dis[from]));
        while(!qq.empty())
        {
            H h= qq.top();
            qq.pop();
            int u=h.u;
            if(mark[u])
                continue;
            mark[u]=true;
            int old_d=h.dis;
 
            for(int i=0;i<G[u].size();i++)
            {
                E new_E=edges[G[u][i]];
                if(dis[new_E.to]>new_E.weight+old_d )
                {
                    paths[new_E.to]=paths[u];
                    dis[new_E.to]=new_E.weight+old_d;
                    all_nums[new_E.to]=nums[new_E.to]+all_nums[u];
                }
                else if(dis[new_E.to]==new_E.weight+old_d )
                {
                    paths[new_E.to]+=paths[u];
                    if(all_nums[new_E.to]<all_nums[u]+nums[new_E.to])
                    {
                        all_nums[new_E.to]=all_nums[u]+nums[new_E.to];
                    }
                }
                qq.push(H(new_E.to,dis[new_E.to]));
            }
        }//while
        cout<<paths[to]<<" "<<all_nums[to]<<endl;
 
 
 
    return 0;
}
 
 
 
// priority_queue<E> qq;
// qq.push(E(2,3,4));
// qq.push(E(1,2,2));
// qq.push(E(4,1,3));
// while(!qq.empty())
// {
//     cout<<qq.top().weight<<endl;
//     qq.pop();
// }
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值