Missile Silos CodeForces - 144D
考察: dijkstra+枚举
思路:
先看最短路端点有无答案,再看边上有无答案.
对于每一条边,我们需要找它的最短路径有无答案.
需要分类讨论:
- 一条边的a,b端点.如果a的最短距离>=d,那么肯定没有a的答案.同理b
- 如果a端点小于d,b端点>=d.且dist[a]+len>d那么肯定有a的答案.同理b
- 如果两个端点都小于.此时要看是否会重合.
专属本蒟蒻的坑点:
算法竞赛指南的0x3f3f3f3f是4个记错了就会WA得很惨!1!!
1 #include <iostream> 2 #include <queue> 3 #include <vector> 4 using namespace std; 5 typedef long long ll; 6 typedef pair<int,int> pii; 7 const int N = 2e5+10; 8 int n,m,s,dist[N],h[N],d,ne[N],w[N],e[N],idx; 9 bool st[N]; 10 struct Edge{ 11 int s,e,len; 12 }; 13 void add(int a,int b,int c) 14 { 15 w[idx] = c,e[idx]= b,ne[idx]=h[a],h[a]=idx++; 16 } 17 void dijkstra(int s) 18 { 19 fill(dist,dist+N,0x3f3f3f3f);//WA的原因,初始值小了, 20 priority_queue<pii,vector<pii>,greater<pii> > pq; 21 dist[s] = 0; 22 pq.push({0,s}); 23 while(pq.size()) 24 { 25 auto t = pq.top(); 26 pq.pop(); 27 int v = t.second,di = t.first; 28 if(st[v]) continue; 29 st[v]=1; 30 for(int i=h[v];i!=-1;i=ne[i]) 31 { 32 int j = e[i]; 33 if(dist[j]>w[i]+di){ 34 dist[j] = w[i]+di; 35 pq.push({dist[j],j}); 36 } 37 } 38 } 39 } 40 int main() 41 { 42 ll ans = 0; vector<Edge> v; 43 fill(h,h+N,-1); 44 scanf("%d%d%d",&n,&m,&s); 45 for(int i=1;i<=m;i++) 46 { 47 int a,b,c; 48 scanf("%d%d%d",&a,&b,&c); 49 add(a,b,c); add(b,a,c); 50 Edge ed; ed.s = a; ed.e = b; ed.len = c; 51 v.push_back(ed); 52 } 53 scanf("%d",&d); 54 dijkstra(s); 55 for(int i=1;i<=n;i++) if(dist[i]==d) ans++; 56 for(int i=0;i<v.size();i++) 57 { 58 if(dist[v[i].s]>=d&&dist[v[i].e]>=d) continue; 59 if(dist[v[i].s]>=d&&dist[v[i].e]<d) 60 if(dist[v[i].e]+v[i].len>d) ans++; 61 if(dist[v[i].e]>=d&&dist[v[i].s]<d) 62 if(dist[v[i].s]+v[i].len>d) ans++; 63 if(dist[v[i].e]<d&&dist[v[i].s]<d){ 64 if(dist[v[i].s]+dist[v[i].e]+v[i].len==2*d) ans++; 65 else if(dist[v[i].s]+dist[v[i].e]+v[i].len>2*d) ans+=2; 66 } 67 } 68 printf("%lld\n",ans); 69 return 0; 70 }