Missile Silos CodeForces - 144D

考察: dijkstra+枚举

思路:

        先看最短路端点有无答案,再看边上有无答案.

        对于每一条边,我们需要找它的最短路径有无答案.

需要分类讨论:

  1. 一条边的a,b端点.如果a的最短距离>=d,那么肯定没有a的答案.同理b
  2. 如果a端点小于d,b端点>=d.且dist[a]+len>d那么肯定有a的答案.同理b
  3. 如果两个端点都小于.此时要看是否会重合.

专属本蒟蒻的坑点:

        算法竞赛指南的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 } 

 

posted @ 2021-01-12 20:29  acmloser  阅读(81)  评论(0编辑  收藏  举报