B. Jzzhu and Cities
http://codeforces.com/contest/449/problem/B
题意:给出n个点m条公路k条铁路。
接下来m行 u v w u->v 距离w
然后k行 v w 1->v 距离w
如果修建了铁路并不影响两点的最短距离,那么修铁路是没必要的
求能删掉多少条铁路
思路:
我们把先按照公路和铁路建图,1到铁路v的距离小于w显然这条铁路是没有必要,或者1到铁路重点v距离有多个等于w及度>1 我们也可以删掉这条铁路
代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> using namespace std; #define fio ios_base::sync_with_stdio(false),cin.tie(0); #define Pii pair<int,int> #define INF 0x3f3f3f3f3f3f3f3f #define ll long long const int maxn = 100005; ll dis[maxn]; int head[maxn],To[maxn*20],Len[maxn*20],Next[maxn*20],cnt; int vis[maxn],x[maxn],y[maxn],in[maxn]; void add(int u,int v,int w) { Next[++cnt]=head[u]; head[u]=cnt; To[cnt]=v; Len[cnt]=w; } int k,n,m; priority_queue<Pii,vector<Pii> , greater<Pii> > q; int dij() { dis[1]=0; q.push(Pii(0,1)); while(!q.empty()) { Pii tmp=q.top(); int u=tmp.second; q.pop(); if(vis[u]) continue; vis[u]=1; for(int i=head[u]; i!=-1; i=Next[i]) { int v=To[i]; int d=Len[i]; if(dis[v]>dis[u]+d) { in[v]=1; dis[v]=dis[u]+d; q.push(Pii(dis[v],v)); } else if(dis[v]==dis[u]+d) in[v]++; } } int ans=0; for(int i=1; i<=k; i++) { if(dis[x[i]]<y[i]) ans++; else { if(dis[x[i]]==y[i]&&in[x[i]]>1) { in[x[i]]--; ans++; } } } return ans; } int main() { scanf("%d %d %d",&n,&m,&k); for(int i=0; i<=n; i++) { dis[i]=INF; } memset(head,-1,sizeof(head)); for(int i=1; i<=m; i++) { int u,v,w; scanf("%d %d %d",&u,&v,&w); add(u,v,w); add(v,u,w); } for(int i=1; i<=k; i++) { int v,w; scanf("%d %d",&x[i],&y[i]); add(1,x[i],y[i]); add(x[i],1,y[i]); } cout<<dij()<<endl; return 0;
PS:摸鱼怪的博客分享,欢迎感谢各路大牛的指点~