题目简述
一张无项图有 n n n个点, m m m条边。再给你 k k k条边,问这些边最少可以保留多少,仍使点 1 1 1到每个店的距离不变。
思路
先将 k k k个点上岛(设为最短路),再看剩下的边能否松弛这些点,如果可以就说明这个点与 1 1 1的边可以删除。
code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, INF = 2e9;
int cnt;
int head[N];
vector <pair<int ,int > > g[N];
int n, m, k;
bool vis[N];
long long dis[N];
bool book[N];
queue <int> q;
void dij()
{
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for (int i = 0; i < g[u].size(); i++)
{
int v = g[u][i].first;
int w = g[u][i].second;
if (dis[v] >= dis[u] + w)
{
dis[v] = dis[u] + w;
book[v] = 0;
if (!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}
int main()
{
int u, v, w;
memset(head, -1, sizeof(head));
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) dis[i] = INF;
for (int i = 1; i <= m; i++)
{
cin >> u >> v >> w;
g[u].push_back(make_pair(v,w));
g[v].push_back(make_pair(u,w));
}
q.push(1);
dis[1] = 0;
vis[1] = 1;
for(int i = 1; i <= k; i++)
{
cin >> v >> w;
if (w < dis[v])
{
dis[v] = w;
vis[v] = 1;
book[v] = 1;
q.push(v);
}
}
dij();
int ans = 0;
for(int i = 1; i <= n; i++)
if(book[i]) ans++;
cout << k - ans << endl;
return 0;
}