codeforces 144 D. Missile Silos 最短路

链接:http://codeforces.com/problemset/problem/144/D

D. Missile Silos

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

A country called Berland consists of n cities, numbered with integer numbers from 1 to 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 nm 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 viuiwi (1?≤?vi,?ui?≤?nvi?≠?ui,1?≤?wi?≤?1000),
where viui 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.

Sample test(s)

input

4 6 1
1 2 1
1 3 3
2 3 1
2 4 1
3 4 1
1 4 2
2

output

3

input

5 6 3
3 1 1
3 2 1
3 4 1
3 5 1
1 2 6
4 5 8
4

output

3

Note

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 1from
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 distance3 from city 4 in
the direction to city 5 and at a distance 3 from
city 5 to city 4.

题意:给你一个图。 问图中 有多少点  和起点的最短距离是len。边上的点也算。

做法:

把点最近距离 算好。

然后 边上 分两种情况。

if(l1<len&&l2<len&&l1+l2+dis==2*len)

ans++;

这种情况是,两边到这个点都是最短的。这个点只用计数一次。

if(l1<len&&l1+dis>len&&l2+(dis-(len-l1))>len)

ans++;

if(l2<len&&l2+dis>len&&l1+(dis-(len-l2))>len)

ans++;

这两种情况 就是讨论 在最短距离为len的点 在这条边上。 然后两边都判断下。

双向边重复计数了,所以边上的计算的答案 ans/=2

//http://codeforces.com/problemset/problem/144/D

#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map>

using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=100010;
struct qnode
{
	int u;
	int v;
	int c;
	qnode(int _v=0,int _c=0):v(_v),c(_c){}
	bool operator <(const qnode &r)const
	{
		return c>r.c;
	}
};
struct Edge
{
	int u,v,cost;
	Edge(int _u=0,int _v=0,int _cost=0):u(_u),v(_v),cost(_cost){}
};
vector<Edge>E[MAXN];
bool vis[MAXN];
int dist[MAXN];
void Dijkstra(int n,int start)//点的编号从1开始
{
	memset(vis,false,sizeof(vis));
	for(int i=1;i<=n;i++)dist[i]=INF;
	priority_queue<qnode>que;
	while(!que.empty())que.pop();
	dist[start]=0;
	que.push(qnode(start,0));
	qnode tmp;
	while(!que.empty())
	{
		tmp=que.top();
		que.pop();
		int u=tmp.v;
		if(vis[u])continue;
		vis[u]=true;
		for(int i=0;i<E[u].size();i++)
		{
			int v=E[tmp.v][i].v;
			int cost=E[u][i].cost;
			if(!vis[v]&&dist[v]>dist[u]+cost)
			{
				dist[v]=dist[u]+cost;
				que.push(qnode(v,dist[v]));
			}
		}
	}
}
void addedge(int u,int v,int w)
{
	E[u].push_back(Edge(u,v,w));
}

int main()
{
	int n,m,sta;
	while(scanf("%d%d%d",&n,&m,&sta)!=EOF)
	{
		memset(E,0,sizeof E);
		while(m--)
		{
			int u,v,cost;
			scanf("%d%d%d",&u,&v,&cost);
			addedge(u,v,cost);
			addedge(v,u,cost);
		}
		__int64 len;
		scanf("%I64d",&len);
		Dijkstra(n,sta);
		int ans=0;

		for(int i=1;i<=n;i++)//所有的点
		{
			for(int j=0;j<E[i].size();j++)// 所有的边
			{
				int l1=dist[i];
				int l2=dist[E[i][j].v];

				int dis=E[i][j].cost;
				int v=E[i][j].v;
				if(l1<len&&l2<len&&l1+l2+dis==2*len)
					ans++;

				if(l1<len&&l1+dis>len&&l2+(dis-(len-l1))>len)
					ans++;

				if(l2<len&&l2+dis>len&&l1+(dis-(len-l2))>len)
					ans++;
			}
		}
		ans/=2;
		for(int i=1;i<=n;i++)
		{
			if(dist[i]==len)
			{
			//	printf("dian %d\n",i);
				ans++;
			}
		}
		cout<<ans<<endl;

	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-12 09:43:30

codeforces 144 D. Missile Silos 最短路的相关文章

codeforces 144D Missile Silos(最短路)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Missile Silos A country called Berland consists of n cities, numbered with integer numbers from 1 to n. Some of them are connected by bidirectional roads. Each road has some length. There is

CF 144D Missile Silos [最短路+想法]

题意: 给出一张图和图上的一个顶点,求距离这个点距离为s(最短距离)的顶点或边上的点总共有几个(边上的点要保证也是最短距离) 分析: 先用DIJ求出最短路 然后对所有顶点,距离为s的点都算上 枚举每条边 边上的两个顶点如果距离不够,则看在边上能不能找到一个点,顶点上的距离加上这个顶点到点的距离能为s(注意保证这个距离是最小距离(即这个点通过另外一端的顶点距离源点的距离小大于这个s)).数出这样的点的个数,加上.注意重合点的情况,有的边上一个这样的点都没有,有的只有1个,有的有两个点,有的两个点重

最短路 Codeforces Round #103 (Div. 2) D. Missile Silos

题目传送门 1 /* 2 最短路: 不仅扫描边,还要扫描点:点有两种情况,一种刚好在中点,即从u,v都一样,那么最后/2 3 还有一种是从u,v不一样,两种的距离都是l 4 模板错了,逗了好久:( 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #include <cmath> 10 #include <vector> 11 #include <q

Codeforces 144D. Missile Silos【dijkstra】

题目大意: 给出一个图,一个源点s,问距离这个源点的最短距离恰好为 l 的点有多少个(这个点可以在边上,可以在节点上). 做法: 首先用dijkstra算法求出每个节点到s的最短路d[]数组,然后对于每条边w(u,v)来说有下面三种情况是合法的: 1:d[u]<l && l-d[u]<w(u,v) && d[v]+w(u,v)-(l-d[u])>l 2:d[v]<l && l-d[v]<w(u,v) && d[u

Codeforces 449B Jzzhu and Cities(最短路)

题目链接:Codeforces 449B Jzzhu and Cities 题目大意:Jzzhu是一个国家的总统,这个国家有N座城市,以1为首都,已经存在了M条公路,给定M条路.并且还有K条铁轨,铁轨均有首都出发,连接si,距离为yi.现在Jzzhu想要节省经费,拆除一些铁轨,问说最多能拆除多少个铁轨,要求每座城市与首都的最短距离不变. 解题思路:最短路,多加一个标记数组,每个si标记1,如果这些点的最短距离被更新,则将对应si的标记清为0,最后统计一下剩余的标记,即为不能拆除的铁轨. #inc

CodeForces 709B Checkpoints (数学,最短路)

题意:给定你的坐标,和 n 个点,问你去访问至少n-1个点的最短路是多少. 析:也是一个很简单的题,肯定是访问n-1个啊,那么就考虑从你的位置出发,向左访问和向右访问总共是n-1个,也就是说你必须从1 - n-1 全访问一次, 或者是2 - n 全访问一次,有一段是访问了两次,加上就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <s

[ An Ac a Day ^_^ ] CodeForces 601A The Two Routes 最短路

14号就ccpc全国赛的全国赛了 而且也快东北赛的选拔赛了 现在队伍实力实在不行 参加了也是边缘化的队伍 虽然有新生保护的设置 但实话说 机会还是不大 所以不如趁现在开始好好努力 明年也许还有机会 An Ac a Day ( of course not keep a girl away ^_^ ) 题意呢 一个人开火车 一个人开大巴 火车走铁路 大巴走公路 现在有n个城镇 每两个城镇之间都有路 其中m条铁路 其他的都是公路 要求两个人都从1开始走 途中不相遇 问最快要多久 题面比较诡异 两个人

codeforces 689B Mike and Shortcuts 最短路

题目大意:给出n个点,两点间的常规路为双向路,路长为两点之间的差的绝对值,第二行为捷径,捷径为单向路(第i个点到ai点),距离为1.问1到各个点之间的最短距离. 题目思路:SPFA求最短路 #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<stdio.h> #include<stdlib.h> #include<q

Codeforces 715B. Complete The Graph 最短路,Dijkstra,构造

原文链接https://www.cnblogs.com/zhouzhendong/p/CF715B.html 题解 接下来说的“边”都指代“边权未知的边”. 将所有边都设为 L+1,如果dis(S,T) < L ,那么必然无解. 将所有边都设为 1 ,如果 dis(S,T) > L ,那么必然无解. 考虑将任意一条边的权值+1,则 dis(S,T) 会 +0 或者 +1 . 如果将所有边按照某一个顺序不断+1,直到所有边的权值都是L+1了,那么在这个过程中,dis(S,T) 是递增的,而且一定