CodeChef:Two Closest(最短路 & 思维)
2017-09-06 11:54
429 查看
You are given a weighted graph with N nodes and M edges. Some of the nodes are marked as special nodes.
Your task is to find the shortest pairwise distance between any two different special nodes.
The first line of the input contains three space-separated integers N, M and K denoting
the number of nodes, the number of edges, and the number of special nodes.
The following line contains K space-separated distinct integers A1, A2, ..., AK ,
denoting the special nodes.
Each of the following M lines (say, the jth) contains a triple Xj Yj Zj,
denoting the edge connecting the nodes Xj and Yj, and having the weight of Zj.
Output the shortest pairwise distance between any two different special nodes.
2 ≤ K ≤ N
The given graph is connected.
The given graph doesn't contain self loops and multiple edges.
1 ≤ Ai ≤ N
1 ≤ Zj ≤ 104
1 ≤ Xj, Yj ≤ N
Subtask #1 (20 points): 2 ≤ N ≤ 300, N-1 ≤ M ≤ N*(N-1)/2, 2 ≤ K ≤ N
Subtask #2 (25 points): 2 ≤ N ≤ 105, N-1 ≤ M ≤ 105, 2 ≤ K ≤ 10
Subtask #3 (55 points): 2 ≤ N ≤ 105, N-1 ≤ M ≤ 3
* 105, 2 ≤ K ≤ 104
Nodes 1, 3 and 5 are special nodes. Shortest distance between nodes 1 and 3 is 7 and that between nodes 3 and 5 is 9. Shortest distance between nodes 1 and 5 is 16. Minimum of these distances is 7. Hence answer is 7.
题意:给一个无向图,K个特殊点,问这K个点中最近的两个点的距离。
思路:特殊点任取一个作为起点跑dijk遇到另外的特殊点就结束,更新最短距离imin,从下一个特殊点开始继续跑,超过imin就break,显然复杂度O(NlogN)。
# include <bits/stdc++.h>
# define pb push_back
# define mp make_pair
# define pii pair<int,int>
# define A first
# define B second
using namespace std;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
int a[maxn], vis[maxn], dis[maxn];
vector<pii >g[maxn];
priority_queue<pii, vector<pii >, greater<pii > >q;
int main()
{
int t, n, m, k, u, v, w, cnt, imin = INF;
scanf("%d%d%d",&n,&m,&k);
for(int i=0; i<k; ++i)
{
scanf("%d",&t);
a[t] = 1;
}
for(int i=0; i<m; ++i)
{
scanf("%d%d%d",&u,&v,&w);
g[u].pb(mp(v,w));
g[v].pb(mp(u,w));
}
for(int i=1; i<=n; ++i)
{
if(!a[i]) continue;
for(int j=1; j<=n; ++j) dis[j] = INF, vis[j] = 0;
cnt = dis[i] = 0;
while(!q.empty()) q.pop();
q.push(mp(0, i));
while(!q.empty())
{
int u = q.top().B;
q.pop();
vis[u] = 1;
cnt += a[u];
if(dis[u] > imin) break;
if(cnt == 2)
{
imin = min(imin, dis[u]);
break;
}
for(auto j : g[u])
{
int v = j.A, w = j.B;
if(vis[v]) continue;
if(dis[v] > dis[u]+w)
{
dis[v] = dis[u]+w;
q.push(mp(dis[v], v));
}
}
}
}
printf("%d\n",imin);
return 0;
}
Your task is to find the shortest pairwise distance between any two different special nodes.
Input
The first line of the input contains three space-separated integers N, M and K denotingthe number of nodes, the number of edges, and the number of special nodes.
The following line contains K space-separated distinct integers A1, A2, ..., AK ,
denoting the special nodes.
Each of the following M lines (say, the jth) contains a triple Xj Yj Zj,
denoting the edge connecting the nodes Xj and Yj, and having the weight of Zj.
Output
Output the shortest pairwise distance between any two different special nodes.
Constraints
2 ≤ K ≤ NThe given graph is connected.
The given graph doesn't contain self loops and multiple edges.
1 ≤ Ai ≤ N
1 ≤ Zj ≤ 104
1 ≤ Xj, Yj ≤ N
Subtasks
Subtask #1 (20 points): 2 ≤ N ≤ 300, N-1 ≤ M ≤ N*(N-1)/2, 2 ≤ K ≤ NSubtask #2 (25 points): 2 ≤ N ≤ 105, N-1 ≤ M ≤ 105, 2 ≤ K ≤ 10
Subtask #3 (55 points): 2 ≤ N ≤ 105, N-1 ≤ M ≤ 3
* 105, 2 ≤ K ≤ 104
Example
Input: 5 5 3 1 3 5 1 2 3 2 3 4 3 4 1 4 5 8 1 5 19 Output: 7
Explanation
Nodes 1, 3 and 5 are special nodes. Shortest distance between nodes 1 and 3 is 7 and that between nodes 3 and 5 is 9. Shortest distance between nodes 1 and 5 is 16. Minimum of these distances is 7. Hence answer is 7.题意:给一个无向图,K个特殊点,问这K个点中最近的两个点的距离。
思路:特殊点任取一个作为起点跑dijk遇到另外的特殊点就结束,更新最短距离imin,从下一个特殊点开始继续跑,超过imin就break,显然复杂度O(NlogN)。
# include <bits/stdc++.h>
# define pb push_back
# define mp make_pair
# define pii pair<int,int>
# define A first
# define B second
using namespace std;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
int a[maxn], vis[maxn], dis[maxn];
vector<pii >g[maxn];
priority_queue<pii, vector<pii >, greater<pii > >q;
int main()
{
int t, n, m, k, u, v, w, cnt, imin = INF;
scanf("%d%d%d",&n,&m,&k);
for(int i=0; i<k; ++i)
{
scanf("%d",&t);
a[t] = 1;
}
for(int i=0; i<m; ++i)
{
scanf("%d%d%d",&u,&v,&w);
g[u].pb(mp(v,w));
g[v].pb(mp(u,w));
}
for(int i=1; i<=n; ++i)
{
if(!a[i]) continue;
for(int j=1; j<=n; ++j) dis[j] = INF, vis[j] = 0;
cnt = dis[i] = 0;
while(!q.empty()) q.pop();
q.push(mp(0, i));
while(!q.empty())
{
int u = q.top().B;
q.pop();
vis[u] = 1;
cnt += a[u];
if(dis[u] > imin) break;
if(cnt == 2)
{
imin = min(imin, dis[u]);
break;
}
for(auto j : g[u])
{
int v = j.A, w = j.B;
if(vis[v]) continue;
if(dis[v] > dis[u]+w)
{
dis[v] = dis[u]+w;
q.push(mp(dis[v], v));
}
}
}
}
printf("%d\n",imin);
return 0;
}
相关文章推荐
- [分治最短路 && 树链剖分]Codechef September Challenge 2017 QGRID. Querying on a Grid
- CodeChef:Chef and Subsequences(思维 & dfs)
- CodeChef:Magic Board(思维 & 树状数组)
- CodeChef:A temple of Snakes(思维 & 二分)
- CodeChef:Desik And Divisors(数学 & 二分 & 思维)
- CF&&CC百套计划2 CodeChef December Challenge 2017 Penalty Shoot-out
- CodeChef:Travel to all Points(二分 & 技巧)
- CodeChef:Company and Club Hierarchies(树形dp & 技巧)
- SDOI DAY1 T1 & CodeChef Divisible Subset 前缀和抽屉原理
- AtCoder:Chef Hates Palindromes(思维 & 字符串)
- CF&&CC百套计划2 CodeChef December Challenge 2017 Total Diamonds
- CodeChef:Skiing(优先队列 & BFS)
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef and Hamming Distance of arrays
- C - A Game of Balls CodeChef - GAMEBALL 思维模拟
- [BZOJ4408&&BZOJ4299][FJOI2016 && Codechef]神秘数&&FRBSUM(主席树)
- CodeChef "Chef and Churus" 分块+树状数组
- CodeChef - AMJMP Jump on Buildings 【dp + 思维】
- 4408: [Fj Winter Camp 2016]神秘数&&4299: Codechef FRBSUM|主席树
- BZOJ 3426 && CodeChef/CHANGE
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries