CodeForces-449B(シングルソース最短、思考)

リンク:

https://vjudge.net/problem/CodeForces-449B

質問の意味:

Jzzhuは彼の国に1からnまでの番号のn都市があり、国Aの社長です。市1は、また都市を結ぶメートル道路があるA.の首都です。一つは、i番目の道路を使用してviに街のUIから行く(およびその逆)することができ、この道の長さはXIです。最後に、国におけるk列車のルートがあります。一つは、このルートの長さはYIある都市SI(およびその逆)への国の首都から行くためにi番目の列車のルートを使用することができます。

Jzzhuは、国のお金を無駄にしたくないので、彼は電車の路線の一部を閉鎖する予定です。Jzzhuに以下の条件の下で閉じることができる列車のルートの最大数を教えてください:資本へのすべての都市からの最短経路の長さは変更してはなりません。

アイデア:

最短各ポイントでいくつかがあります記録しながら、まず、各点への最短経路を求める。
最後に、各列車のトラックを比較し、それを削除することができます。

コード:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
//#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
#include <string>
#include <assert.h>
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;

const int MAXN = 1e6+10;
const long long INF = 1e15;

struct Edge
{
    int to;
    LL v;
};

struct HeapNode
{
    int to;
    LL dis;
    bool  operator < (const HeapNode& that) const
    {
        return this->dis > that.dis;
    }
};

vector<Edge> G[MAXN];
int In[MAXN], Vis[MAXN];
LL Dis[MAXN];
int To[MAXN], Va[MAXN];
int n, m, k;

void Dij()
{
    memset(Vis, 0, sizeof(Vis));
    memset(In, 0, sizeof(In));
    In[1] = 1;
    for (int i = 1;i <= n;i++)
        Dis[i] = INF;
    Dis[1] = 0;
    priority_queue<HeapNode> que;
    que.push(HeapNode{1, 0LL});
    while (!que.empty())
    {
        HeapNode node = que.top();
        que.pop();
        if (Vis[node.to])
            continue;
        Vis[node.to] = 1;
        for (int i = 0;i < G[node.to].size();i++)
        {
            int ne = G[node.to][i].to;
            if (Vis[ne])
                continue;
            LL va = G[node.to][i].v;
            if (Dis[ne] == Dis[node.to]+va)
                In[ne]++;
            if (Dis[ne] > Dis[node.to]+va)
            {
                In[ne]=1;
                Dis[ne] = Dis[node.to]+va;
            }
            que.push(HeapNode{ne, Dis[ne]});
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int u, v, w;
    cin >> n >> m >> k;
    for (int i = 1;i <= m;i++)
    {
        cin >> u >> v >> w;
        G[u].push_back(Edge{v, w});
        G[v].push_back(Edge{u, w});
    }
    for (int i = 1;i <= k;i++)
    {
        cin >> v >> w;
        To[i] = v, Va[i] = w;
        G[1].push_back(Edge{v, w});
    }
    Dij();
//    for (int i = 1;i <= n;i++)
//        cout << Dis[i] << ' ' ;
//    cout << endl;
    int num = 0;
    for (int i = 1;i <= k;i++)
    {
        if (Dis[To[i]] < Va[i])
            num++;
        else if (Dis[To[i]] == Va[i] && In[To[i]] > 1)
            num++, In[To[i]]--;
    }
    cout << num << endl;

    return 0;
}

おすすめ

転載: www.cnblogs.com/YDDDD/p/11367121.html
おすすめ