【CodeForces - 144D】Missile Silos(单源最短路,枚举中间边,枚举情况可能性)
題干:
A country called Berland consists of?n?cities, numbered with integer numbers from?1to?n. Some of them are connected by bidirectional roads. Each road has some length. There is a path from each city to any other one by these roads. According to some Super Duper Documents, Berland is protected by the Super Duper Missiles. The exact position of the Super Duper Secret Missile Silos is kept secret but Bob managed to get hold of the information. That information says that all silos are located exactly at a distance?l?from the capital. The capital is located in the city with number?s.
The documents give the formal definition: the Super Duper Secret Missile Silo is located at some place (which is either city or a point on a road) if and only if the shortest distance from this place to the capital along the roads of the country equals exactly?l.
Bob wants to know how many missile silos are located in Berland to sell the information then to enemy spies. Help Bob.
Input
The first line contains three integers?n,?m?and?s?(2?≤?n?≤?105,?,?1?≤?s?≤?n) — the number of cities, the number of roads in the country and the number of the capital, correspondingly. Capital is the city no.?s.
Then?m?lines contain the descriptions of roads. Each of them is described by three integers?vi,?ui,?wi?(1?≤?vi,?ui?≤?n,?vi?≠?ui,?1?≤?wi?≤?1000), where?vi,?ui?are numbers of the cities connected by this road and?wi?is its length. The last input line contains integer?l?(0?≤?l?≤?109) — the distance from the capital to the missile silos. It is guaranteed that:
- between any two cities no more than one road exists;
- each road connects two different cities;
- from each city there is at least one way to any other city by the roads.
Output
Print the single number — the number of Super Duper Secret Missile Silos that are located in Berland.
Examples
Input
4 6 1 1 2 1 1 3 3 2 3 1 2 4 1 3 4 1 1 4 2 2Output
3Input
5 6 3 3 1 1 3 2 1 3 4 1 3 5 1 1 2 6 4 5 8 4Output
3Note
In the first sample the silos are located in cities?3?and?4?and on road?(1,?3)?at a distance?2?from city?1?(correspondingly, at a distance?1?from city?3).
In the second sample one missile silo is located right in the middle of the road?(1,?2). Two more silos are on the road?(4,?5)?at a distance?3?from city?4?in the direction to city?5?and at a distance?3?from city?5?to city?4.
題目大意:
? ? ?圖中有n個(gè)點(diǎn),m條無向邊,一個(gè)起點(diǎn),問有距離原點(diǎn)最短距離為l的地方有幾個(gè)(在邊上或者在點(diǎn)上都算)。
解題報(bào)告:
? ?這題思路還是很清晰的啊,但是1WA了因?yàn)殚_數(shù)組應(yīng)該是2e5,因?yàn)槭菬o向圖啊!!我記得之前就在這錯(cuò)過。
? 首先把在點(diǎn)上的處理了,然后枚舉每一條邊分四種情況分別列出來,其中最后一種再分三種情況列出來就好了:
1.先可以設(shè)定的點(diǎn)在u,v中間,
2.可以設(shè)定的點(diǎn)更加靠近u,這樣只需要滿足求出的那個(gè)點(diǎn),經(jīng)過v再到原點(diǎn)的距離>L 就可以ans++了;
3.可以設(shè)定的點(diǎn)更加靠近v,這樣只需要滿足求出的那個(gè)點(diǎn),經(jīng)過u到原點(diǎn)的距離>L就可以ans++了。
對(duì)應(yīng)將三種情況分別枚舉出來,維護(hù)ans即可。(2和3比較難繞,但是可以從答案貢獻(xiàn)的角度反面考慮,就不難證明正確性。)
AC代碼:
#include<cstdio> #include<queue> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAX = 2e5 +5; const int INF = 0x3f3f3f3f; int n,m,s; int id,ans; int head[MAX]; int dis[MAX]; bool vis[MAX]; struct Node {int fm,to,w;int ne; } e[MAX]; struct Point {int pos;int c;Point(){}Point(int pos,int c):pos(pos),c(c){}bool operator <(const Point & b) const {return c > b.c;} }; void add(int u,int v,int w) {e[++id].fm=u;e[id].to = v;e[id].w = w;e[id].ne = head[u];head[u] = id; } void Dijkstra(int u) {memset(dis,INF,sizeof dis);dis[u] = 0;memset(vis,0,sizeof vis);priority_queue<Point> pq;pq.push(Point(u,0));while(!pq.empty()) {Point cur = pq.top();pq.pop();if(vis[cur.pos] == 1) continue;vis[cur.pos] = 1;for(int i = head[cur.pos]; i!=-1; i=e[i].ne) {if(vis[e[i].to]) continue;if(dis[e[i].to] > dis[cur.pos] + e[i].w) {dis[e[i].to] = dis[cur.pos] + e[i].w;pq.push(Point(e[i].to,dis[e[i].to]));}}} } int main() {cin>>n>>m>>s;memset(head,-1,sizeof head);ans = 0;int a,b,w,L;for(int i = 1; i<=m; i++) {scanf("%d%d%d",&a,&b,&w);add(a,b,w);add(b,a,w);}cin>>L;Dijkstra(s);for(int i = 1; i<=n; i++) {if(dis[i] == L) ans++;}//枚舉每一條邊 for(int i = 1; i<=id; i+=2) {int u = e[i].fm,v = e[i].to,w = e[i].w;if(dis[u] >= L && dis[v] >= L) continue;if(dis[u] >= L && dis[v] < L) {if(dis[v] + w > L) ans++; }else if(dis[v] >=L && dis[u] < L) {if(dis[u] + w > L) ans++;}else {int disu = L - dis[u],disv = L - dis[v];//計(jì)算一下多出來的那一塊if(disu + disv == w) ans++;else {if(disu < w && dis[v] + (w-disu) > L) ans++;//別忘了disu < wif(disv < w && dis[u] + (w-disv) > L) ans++; }}}printf("%d\n",ans);return 0 ; }?
總結(jié)
以上是生活随笔為你收集整理的【CodeForces - 144D】Missile Silos(单源最短路,枚举中间边,枚举情况可能性)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信用卡逾期还款后还能用吗 你需要知道的
- 下一篇: 富国基金有哪些值得推荐的基金?富国基金的