题目大意:这个国家有n个城市,编号1-n,编号1的城市为首都,城市之间有m条双向道路连接,同时有k条火车路线可以直接让其他城市与首都城市连接,每条火车路线也存在自己的距离长度,因为火车路线的修建存在一定花费,现在需要保证首都在其余的n-1个城市的距离最短的情况下,去除一些没没必要的火车路径,问最多能去除几条。
题解思路:在用dijkstra 求最短路时,其实最短路的条数是可以确定的。这个题就利用了这一点,把火车,汽车都加在同一个图里,找首都到所有点的最短路,以及最短路的条数,如果直达某城市的火车线小于最短路,明显可以去了这个火车线,如果相等,那么就得根据最短路的条数决定了。
#include<bits/stdc++.h> using namespace std; #define maxn 100005 #define ll long long typedef pair<ll,int> PII; const ll INF=9e18+7; const int mod = 1e9+7; int n,m,k; int road[maxn]; ll kk[maxn]; ll dis[maxn]; struct node{ ll to,cost; node(ll x,ll y){ to=x; cost=y; } }; vector<node>v[maxn]; void dijkstra(int x){ priority_queue<PII,vector<PII>,greater<PII> >q; for(int i=0;i<=n;i++)dis[i]=INF; dis[x]=0; q.push(PII(0,x)); while(!q.empty()){ PII p=q.top();q.pop(); ll len=p.first;int d=p.second; if(dis[d]<len)continue; for(int i=0;i<v[d].size();i++){ node e=v[d][i]; ll len2=e.cost+len; if(dis[e.to]>len2){ dis[e.to]=len2; road[e.to]=0; q.push(PII(dis[e.to],e.to)); } else if(dis[e.to]==dis[d]+e.cost)road[e.to]++; } } } int main() { scanf("%d %d %d",&n,&m,&k); for(int i=1;i<=m;i++){ ll a,b,c; scanf("%lld %lld %lld",&a,&b,&c); v[a].push_back(node(b,c)); v[b].push_back(node(a,c)); } int cnt=0; for(int i=1;i<=k;i++){ int a;ll b; scanf("%d %lld",&a,&b); if(kk[a]==0)kk[a]=b; else{ if(kk[a]>b)kk[a]=b; cnt++; } } for(int i=2;i<=n;i++){ if(kk[i]==0)continue; v[1].push_back(node(i,kk[i])); v[i].push_back(node(1,kk[i])); } dijkstra(1); for(int i=2;i<=n;i++){ if(kk[i]!=0){ if(dis[i]<kk[i])cnt++; else if(dis[i]==kk[i]&&road[i]>0)cnt++; } } printf("%d",cnt); }