zoukankan      html  css  js  c++  java
  • Jzzhu and Cities(最短路计数)

    题目链接

    题目大意:这个国家有n个城市,编号1-n,编号1的城市为首都,城市之间有m条双向道路连接,同时有k条火车路线可以直接让其他城市与首都城市连接,每条火车路线也存在自己的距离长度,因为火车路线的修建存在一定花费,现在需要保证首都在其余的n-1个城市的距离最短的情况下,去除一些没没必要的火车路径,问最多能去除几条

    题解思路:在用dijkstra 求最短路时,其实最短路的条数是可以确定的。这个题就利用了这一点,把火车,汽车都加在同一个图里,找首都到所有点的最短路,以及最短路的条数,如果直达某城市的火车线小于最短路,明显可以去了这个火车线,如果相等,那么就得根据最短路的条数决定了。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define maxn 100005
    #define ll long long
    typedef pair<ll,int> PII;
    
    const ll INF=9e18+7;
    const int mod = 1e9+7;
    
    int n,m,k;
    int road[maxn];
    ll kk[maxn];
    ll dis[maxn];
    struct node{
        ll to,cost;
        node(ll x,ll y){
            to=x;
            cost=y;
        }
    };
    vector<node>v[maxn];
    
    void dijkstra(int x){
        priority_queue<PII,vector<PII>,greater<PII> >q;
        for(int i=0;i<=n;i++)dis[i]=INF;
        dis[x]=0;
        q.push(PII(0,x));
        while(!q.empty()){
            PII p=q.top();q.pop();
            ll len=p.first;int d=p.second;
            if(dis[d]<len)continue;
            for(int i=0;i<v[d].size();i++){
                node e=v[d][i];
                ll len2=e.cost+len;
                if(dis[e.to]>len2){
                    dis[e.to]=len2;
                    road[e.to]=0;
                    q.push(PII(dis[e.to],e.to));
                }
                else if(dis[e.to]==dis[d]+e.cost)road[e.to]++;
            }
        }
    }
    
    int main()
    {
        scanf("%d %d %d",&n,&m,&k);
        for(int i=1;i<=m;i++){
            ll a,b,c;
            scanf("%lld %lld %lld",&a,&b,&c);
            v[a].push_back(node(b,c));
            v[b].push_back(node(a,c));
        }
        int cnt=0;
        for(int i=1;i<=k;i++){
            int a;ll b;
            scanf("%d %lld",&a,&b);
            if(kk[a]==0)kk[a]=b;
            else{
                if(kk[a]>b)kk[a]=b;
                cnt++;
            }
        }
        for(int i=2;i<=n;i++){
            if(kk[i]==0)continue;
            v[1].push_back(node(i,kk[i]));
            v[i].push_back(node(1,kk[i]));
        }
        dijkstra(1);
        for(int i=2;i<=n;i++){
            if(kk[i]!=0){
                if(dis[i]<kk[i])cnt++;
                else if(dis[i]==kk[i]&&road[i]>0)cnt++;
            }
        }
        printf("%d",cnt);
    }
  • 相关阅读:
    Android基础
    Android基础
    Java小项目——多线程弹球
    Java小项目——抽奖系统
    Java小项目——五子棋
    Java小项目——画板
    Java基础——swing登录界面
    Java基础——类的继承
    实验室资料说明
    20180919 百信、百度面试
  • 原文地址:https://www.cnblogs.com/Mmasker/p/11917473.html
Copyright © 2011-2022 走看看