zoukankan      html  css  js  c++  java
  • [CF449B] Jzzhu and Cities

    Description

    (n) 个点 (m) 条边的无向图,另有 (k) 条特殊边连接 (1-i),问最多删除多少条特殊边,使得每个点到 (1) 的最短距离不变。

    Solution

    考虑先计算到每个点的最短路条数,然后判断。

    如果 (1 o i) 有特殊边,若特殊边长度 (>) 距离,那么显然这条特殊边没有贡献,直接删除。若等于距离,并且最短路条数 (>1),则删除这条特殊边,并将最短路条数 (-1)

    注意这里 (-1) 以后我们并不需要去考虑它对其它的点的影响。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    int n, m, k, d[N], h[N], spec[N][3], cnt[N], vis[N];
    
    vector<pair<int, int>> g[N];
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
    
    void make(int u, int v, int w)
    {
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }
    
    signed main()
    {
        cin >> n >> m >> k;
        int t1, t2, t3;
        for (int i = 1; i <= m; i++)
        {
            cin >> t1 >> t2 >> t3;
            make(t1, t2, t3);
        }
    
        for(int i=1;i<=k;i++)
        {
            cin>>t1>>t2;
            make(1,t1,t2);
            spec[i][1]=t1;
            spec[i][2]=t2;
        }
    
        memset(d, 0x3f, sizeof d);
        d[1] = 0;
        que.push({0, 1});
    
        while (que.size())
        {
            int p = que.top().second;
            que.pop();
            if (vis[p] == 0)
            {
                vis[p] = 1;
                for (auto pr : g[p])
                {
                    int q = pr.first, w = pr.second;
                    if (d[q] == d[p] + w)
                        ++cnt[q];
                    if (d[q] > d[p] + w)
                    {
                        cnt[q] = 1;
                        d[q] = d[p] + w;
                        que.push({d[q], q});
                    }
                }
            }
        }
    
        int ans = 0;
        for (int i = 1; i <= k; i++)
        {
            if (d[spec[i][1]] < spec[i][2])
                ++ans;
            else if (d[spec[i][1]] == spec[i][2] && cnt[spec[i][1]] > 1)
                ++ans, --cnt[spec[i][1]];
        }
    
        cout << ans << endl;
    }
    
  • 相关阅读:
    Mysql 存储引擎中InnoDB与Myisam的主要区别
    [转]memmove函数
    _Obj* __STL_VOLATILE* __my_free_list
    [转]STL的内存分配器
    [转载]C++ 堆与栈简单的介绍
    [转载]__type_traits
    [转载]C++中 引用&与取地址&的区别
    [转载]delete指针之后应该赋值NULL
    [转载]C++中声明与定义的区别
    学习笔记ubuntu/shell
  • 原文地址:https://www.cnblogs.com/mollnn/p/14095591.html
Copyright © 2011-2022 走看看