题意:一个城市,有m条道路,还有k条铁路(铁路都与点1相连),问在不改变点1到各个点的最短路的前提下最多可以删除多少条铁路
思路:将道路和铁路一起建在同一个图中,跑一遍最短路并记录每个点的入度,接下来有两种情况可以判断可以删除这条铁路。
1,如果最短路比铁路到点1的距离短,那毫无疑问可以删除
2,如果最短路和铁路到点1的距离相同,那么如果入度大于1的话,说明可以通过走别的点到达,不需要铁路所以也可以删除
Trick:INF要开大一点...
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 100005
#define LL long long
int cas=1,T;
const LL INF = 1e17;
int n,m;
struct Edge
{
int from,to,dist;
Edge(int u,int v,int d):from(u),to(v),dist(d){}
};
struct HeapNode
{
int d,u;
bool operator < (const HeapNode&rhs)const
{return d>rhs.d;}
};
vector<Edge>edges;
vector<int>G[maxn];
bool done[maxn];
LL d[maxn];
LL inq[maxn];
struct Dijkstra
{
/* vector<Edge>edges;
vector<int>G[maxn];
bool done[maxn];
LL d[maxn];
LL inq[maxn];*/
void init()
{
for (int i = 0;i<=n;i++)
G[i].clear();
edges.clear();
memset(inq,0,sizeof(inq));
}
void AddEdge(int from,int to,int dist)
{
edges.push_back(Edge(from,to,dist));
int mm = edges.size();
G[from].push_back(mm-1);
}
void dijkstra(int s)
{
priority_queue<HeapNode> q;
for (int i =0;i<=n;i++)
d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
q.push((HeapNode){0,s});
while (!q.empty())
{
HeapNode x = q.top();q.pop();
int u = x.u;
if (done[u])continue;
done[u]=1;
for (int i = 0;i<G[u].size();i++)
{
Edge &e = edges[G[u][i]];
if (d[e.to] == d[u]+e.dist)
inq[e.to]++;
if (d[e.to] > d[u]+e.dist)
{
d[e.to] = d[u] + e.dist;
inq[e.to]=1;
q.push((HeapNode){d[e.to],e.to});
}
}
}
}
};
struct train
{
int v;
LL dist;
}t[maxn];
int main()
{
int k;
scanf("%d%d%d",&n,&m,&k);
Dijkstra dij;
dij.init();
for (int i = 0;i<m;i++)
{
int u,v,di;
scanf("%d%d%d",&u,&v,&di);
dij.AddEdge(u,v,di);
dij.AddEdge(v,u,di);
}
for (int i = 0;i<k;i++)
{
scanf("%d%lld",&t[i].v,&t[i].dist);
dij.AddEdge(1,t[i].v,t[i].dist);
}
dij.dijkstra(1);
LL ans = 0;
for (int i = 0;i<k;i++)
{
if (t[i].dist == d[t[i].v])
if (inq[t[i].v]>1)
{
ans++;
inq[t[i].v]--;
}
if (t[i].dist > d[t[i].v])
ans++;
}
printf("%lld\n",ans);
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}