【题目描述】
【分析】
- 题意:n个点,m条带权边的无向图,其中有k条特殊边连接1和i
- 问最多能删除多少条特殊边,能使每个点到1的最短距离不变
- 解答:直接在原图上跑最短路,得到dis[x]表示x到1的最短路。
- 对于每个用特殊边k连接的点i,如果dis[x]<w[k],那么k可以被删除
- 如果dis[x]=w[k],看x的其他出边如果也在最短路上,那么k也可以被删除
- 如此看来,原题就是一个裸的最短路
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> TQX;
const int N=1e6+10;
int n,m,k,first[N],cnt,val[N],ans,vis[N],dis[N],d[N],where[N],tot[N];
struct node{
int u,v,w,nxt;
}e[N];
void add(int u,int v,int w){
e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w;
e[cnt].nxt=first[u];first[u]=cnt;
}
void dijkstra(int s){
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
priority_queue<TQX,vector<TQX>,greater<TQX> >q;
q.push(make_pair(dis[s],s));
while(!q.empty()){
TQX t=q.top();q.pop();
int d=t.first,u=t.second;
if(vis[u]) continue;
vis[u]=1;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(d+e[i].w==dis[v]) tot[v]++;
if(d+e[i].w<dis[v]){
tot[v]=1;
dis[v]=d+e[i].w;
q.push(make_pair(dis[v],v));
}
}
}
}
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*f;
}
int main(){
n=read();m=read();k=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add(u,v,w);
add(v,u,w);
memset(val,-1,sizeof(val));
for(int i=1;i<=k;i++){
int v=read(),w=read();
add(1,v,w);
d[cnt]=1;
val[i]=w;
where[i]=v;
add(v,1,w);
d[cnt]=1;
}
dijkstra(1);
for(int i=1;i<=k;i++){
int t=where[i],w=val[i];
if(dis[t]<w) ans++;
if(dis[t]==w){
if(tot[t]>1){
ans++;
tot[t]--;
}
}
}
cout<<ans;
return 0;
}