zoukankan      html  css  js  c++  java
  • Codeforces-450D-Jzzhu and Cities+dji

    参考:https://blog.csdn.net/corncsd/article/details/38235973

    传送门:http://codeforces.com/problemset/problem/450/D

    题意:

     有N个地方,M条线路,K条火车路(从1出发)。最多删掉多少火车路使1到每个点的最短路不变。

    思路:

        用dijkstra的思路,优先队列每次找出d最小的。先用火车路更新最小的d。当u的最短路确定的时候,若还是那个火车路,没有被别的路更新,说明这条火车路不能删,若这条路已经被更新过,说明火车路能删。

        怎么判断一个点有没有被更新过呢,这里有个巧妙的方法,一开始把节点编号的负值加到优先队列中,如果最后确定最短路的时候还是负值说明没有被更新过。这个巧妙点还在于,如果存在两个的 first 负值相同,那么,编号为正的一定排在前面,就是说普通路的优先级会比铁路的高;

        有一点要注意,更新条件是d[v]>=d[u]+w,因为如果出现和火车路长度相同的路也要更新,因为这样也可以把火车路删掉。

        把d加入队列的时候可以加d的负值,因为默认的优先队列是先pop大的,负的最大就是正的最小。

    ac代码:

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const ll INF = 1e18+9;
    const int maxn  = 1e5+9;
    ll n, m, k;
    ll dis[maxn];
    bool vis[maxn],vv[maxn];
    vector< pair<ll, ll > >mp[maxn];
    priority_queue< pair<ll ,ll > >q;
    int main(){
        scanf("%lld%lld%lld",&n,&m,&k);
        memset(vv,0,sizeof(vv));
        for(int i=1; i<=m; i++)
        {
            ll u, v;
            ll c;
            scanf("%lld%lld%lld",&u,&v,&c);
            mp[u].pb(make_pair(v,c));
            mp[v].pb(make_pair(u,c));
        }
        for(int i=1; i<=n; i++)
            dis[i] =  INF, vis[i]=false;
        for(int i=1; i<=k; i++)
        {
            ll a;
            ll b;
            scanf("%lld%lld",&a,&b);
            dis[a] = min(dis[a],b);
            q.push(make_pair(-b,-a));
        }
        ll ans = 0;
        dis[1] = 0;
       // vis[1] = true;
        q.push(make_pair(0 , 1));
        while( !q.empty() )
        {
            ll v = q.top().second;
            q.pop();
            if(v<0)
            {
                v = -v;
                if(vis[v]) ans++;
            }
            if(vis[v])continue;
            vis[v]=1;
            for(int i = 0; i < mp[v].size(); i++)
            { 
                ll tmp = mp[v][i].first;
                ll tmpc = mp[v][i].second;
             
                if( dis[tmp] >= dis[v] + tmpc ) 
                {
                    dis[tmp] = dis[v] + tmpc;
                    q.push(make_pair(-1ll*dis[tmp], tmp));
                }
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    众多linux 库及工具意思的解释
    ubuntu root 登录
    Oscillator的参数解释
    世界观和方法论写给学弟学妹的
    元件的降额使用可靠度设计
    电子元件又一话——电感篇
    【转】什么是磁珠(Ferrite Bead 即 FB)
    Digital System Design Guidelines
    几种典型接口的电平标准
    珀耳帖效应
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8735125.html
Copyright © 2011-2022 走看看