Read problems statements in Mandarin Chinese, Russian and Vietnamese as well.
Bearland consists of N cities, numbered 1 through N. Cities are connected with bidirectional roads.
Cities 1 through K were built a long time ago, when citizens liked order and regularity. Each pair of those old cities is connected with a road of length X. Note that this description generates K*(K-1)/2 roads.
There are M newer roads, not necessarily of the same lengths. The i-th of them connects cities ai and bi and has length ci.
There is no road that connects a city to itself. All M+K*(K-1)/2 roads are distinct (ie. no two of them connects the same pair of cities). It's guaranteed that it's possible to get from every city to every other city, using one or more roads.
Limak, a bear, lives in the city S. In order to plan a trip to some other city, for every city he wants to know how quickly he can get there. Can you help him and find the distance from S to every city?
The distance between two cities is the minimum total length of a path (sequence of roads) between the two cities.
Input
The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains five integers N, K, X, M and S, denoting the number of cities, the number of old cities, the length of a road between every two old cities, the number of newer roads, and the city where Limak lives, respectively.
Each of the following M lines contains three integers ai, bi and ci, denoting a road of length ci between cities ai and bi.
As guaranteed above: no two cities are connected with more than one road, no road connects a city to itself, and it's possible to get from every city to every other city.
Output
For each test case, output a single line containing N integers. The i-th of them should denote the distance from the city S to the city i. The distance from S to S is simply 0.
Constraints
- 1 ≤ T ≤ 3
- 2 ≤ K ≤ N ≤ 105
- 0 ≤ M ≤ 105
- 1 ≤ S, ai, bi ≤ N
- 1 ≤ X, ci ≤ 109
Subtasks
- Subtask #1 (45 points): 2 ≤ K ≤ 500
- Subtask #2 (55 points): Original constraints.
Example
Input: 3 5 4 100 2 3 1 5 50 5 3 160 5 4 100 2 3 1 5 50 5 3 140 8 3 15 7 5 3 4 10 4 5 20 5 6 10 6 1 7 3 7 1000 7 8 50 3 5 1000000000 Output: 100 100 0 100 150 100 100 0 100 140 17 32 30 20 0 10 1030 1080
Explanation
Test case 1. There are N = 5 cities. The first K = 4 of them are all connected with each other with roads of length X = 100. There are M = 2 extra roads:
- Cities 1 and 5 are connected with a road of length 50.
- Cities 5 and 3 are connected with a road of length 160.
We are asked to compute distances to all cities from the city S = 3. Note that the distance from a city to itself is 0, and this is why the third number in the ouput is 0.
首先这个题是个最短路,但是有个问题,如果用传统方式存图肯定是会爆的,因为k可以是n,到时后边数就是(100000*99999)/2差不多这么个级别的数。
那我们的主要问题除了读懂题目之外剩下的其实就是去解决这个存变的问题。
我们不要这么耿直,其实我们可以拿出一点来当做一个基站来访问其他的节点。这个节点到其他1-k个节点的权值都是x,而1-k个节点到这个基站的权值是0;
比如说我们拿0来做这个基站,只需要如下操作
for(long long i=1;i<=k;i++)
{
add(i,0,0);
add(0,i,x);
}
然后有了这一步就可以AC了。
#include<bits/stdc++.h>
using namespace std;
const long long M=300000+15;
long long vis[M],cnt,pre[M];
long long dist[M];
long long n;
struct aa
{
long long u,v,next,w;
} edge[M*10];
void add(long long u,long long v,long long w)
{
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=pre[u];
pre[u]=cnt++;
}
void spfa(long long s)
{
dist[s]=0;
queue<int>ycq;
ycq.push(s);
while(!ycq.empty())
{
long long t=ycq.front();
ycq.pop();
vis[t]=0;
for(long long i=pre[t]; i!=-1; i=edge[i].next)
{
long long v=edge[i].v;
long long w=edge[i].w;
if(dist[v]>dist[t]+w)
{
dist[v]=dist[t]+w;
if(!vis[v])
{
vis[v]=1;
ycq.push(v);
}
}
}
}
for(long long i=1;i<=n;i++)
{
if(i==n)
printf("%lld\n",dist[i]);
else
printf("%lld ",dist[i]);
}
}
int main()
{
long long t,k,x,m,s;
scanf("%lld",&t);
while(t--)
{
cnt=0;
scanf("%lld%lld%lld%lld%lld",&n,&k,&x,&m,&s);
for(long long i=0;i<=n;i++)
{
pre[i]=-1;
dist[i]=LONG_LONG_MAX;
vis[i]=0;
}
for(long long i=1;i<=k;i++)
{
add(i,0,0);
add(0,i,x);
}
for(long long i=0;i<m;i++)
{
long long u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
spfa(s);
}
}