题意:城市里有M条道路和K条铁路,问在不影响最短路的情况下,最多能去掉多少条铁路。
这题唯一的难点在于有重边,啥时候铁路能去啥时候不能。
我们记录最短路图里每个点的入度(这里的方法记笔记记笔记)
然后遍历每条铁路,如果铁路长度大于最短路,肯定得去掉。
如果等于,在最短路图入度大于一的情况下可以去掉,然后把入度减一。
居然卡SPFA!!!!!
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
const double EPS=1e-16;
const int MAXN =800010;
const long long INF =0x3f3f3f3f3f3f3f;
typedef long long LL;
int n,m,k;
int tot=0;
int head[MAXN];
struct edge{
int v,next,w;
};
edge e[MAXN];
int vis[MAXN];
LL d[MAXN];
void add(int u,int v,int w){
e[tot].w=w;
e[tot].v=v;
e[tot].next=head[u];
head[u]=tot++;
}
int in[MAXN]={0};
void SPFA(int s)
{
queue <int> que;
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
d[i]=INF;
d[s]=0;
que.push(s);vis[s]=1;
while(!que.empty()){
int u=que.front();que.pop();vis[u]=0;
for(int k=head[u];k!=-1;k=e[k].next)
{
int v=e[k].v,w=e[k].w;
if(d[u]+w==d[v])
in[v]++;
if(d[u]+w<d[v]){
in[v]=1;
d[v]=d[u]+w;
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
}
}
typedef pair <int,int> P;
void dij(int s){
priority_queue<P,vector<P>,greater<P> > que;
fill(d,d+n+1,INF);
d[s]=0;
que.push(P(0,s));
while(!que.empty()){
P p=que.top();
que.pop();
int u=p.second;
if(d[u]<p.first)
continue;
for(int k=head[u];k!=-1;k=e[k].next){
int v=e[k].v;
int w=e[k].w;
if(d[v]==d[u]+w){
in[v]++;
}
if(d[v]>d[u]+w){
d[v]=d[u]+w;
in[v]=1;
que.push(P(d[v],v));
}
}
}
}
int s[MAXN],y[MAXN];
int num=0;
int main()
{
tot=0;
memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
int cnt=0;
for(int i=0;i<k;i++){
scanf("%d%d",s+i,y+i);
add(1,s[i],y[i]);
add(s[i],1,y[i]);
}
dij(1);
for(int i=0;i<k;i++){
if(d[s[i]]<y[i])
cnt++;
else if(d[s[i]]==y[i]){
if(in[s[i]]>1){
in[s[i]]--;
cnt++;
}
}
}
printf("%d\n",cnt);
}