700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > UESTC 1639 云中谁寄锦书来?雁字回时 月满西楼。 Dijkstra拓展

UESTC 1639 云中谁寄锦书来?雁字回时 月满西楼。 Dijkstra拓展

时间:2018-11-25 07:18:13

相关推荐

UESTC 1639 云中谁寄锦书来?雁字回时 月满西楼。     Dijkstra拓展

云中谁寄锦书来?雁字回时,月满西楼。

Time Limit: 6000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)

Submit Status

在干完 TheBigOne(一票大的)之后,劫犯们得准备逃跑路线了。

城市可以看作 n 个点 m 条边的无向图,节点编号为 0 到 n−1,其中有 k 个点为安全屋,劫犯们只要到达其中一个安全屋就能摆脱警察的追捕。

劫犯们从联合储蓄(节点 0)出发,希望能在最短的时间内到达安全屋。

但是警察对劫犯紧追不舍,每当劫犯到达一个节点,警察就立刻封锁与该点相连的边。

由于警力有限,对于当前点警察最多能够封锁与其相连的 d 条边。

现在劫犯想知道,在最坏情况下,他们能到达安全屋的最短时间。

Input

第一行四个整数 n 、m 、k 和 d,含义如上文所描述。

接下来 m 行每行三个整数 u 、v 和 w,表示节点 u 和 v 之间有一条边,且通过该条边要花费 w 的时间。

接下来一行有 k 个整数,表示安全屋所在节点编号。

1≤n≤100000,1≤m≤1000000,0≤k≤n,0≤d≤m,0≤u 、v<n,0≤w≤10000 。

Output

若劫犯们不能到达安全屋,则输出 −1 。

否则输出最坏情况下劫犯们到达安全屋的最短时间。

Sample input and output

Sample Input Sample Output

3 3 1 0 2

0 1 1

1 2 1

0 2 3

2

3 3 1 1 -1

0 1 1

1 2 1

0 2 3

2

Source

UESTC Training for Graph Theory

UESTC 1639 云中谁寄锦书来?雁字回时,月满西楼。

My Solution

题意:在n个点m条边的无向图上,有k个出口从起点出发,每到一个点(包括起点),

该点连出的边中有d条会被封锁,求最坏情况下到达出口的最短路。

Dijkstra拓展

由于求最坏情况下的最短路,对于每个点,显然最优的前d条边不能走。

对于边u->v,必然要先得到v到出口的最坏情况下的最短路才能得到u经过该边再到出口的最坏情况下的最短路,

也就是该边对于u的价值,所以要从出口往回考虑。

令f[i]表示i到出口的最坏情况下的最短路,同dijkstra算法一样,每个点i可以分为f[i]已确定的和f[i]未确定的

初始时自然是对于每个出口x,f[x]=0已确定。

对于f[v]已确定的点v,将边权为w的边u->v以f[v]+w为关键字加入小根堆中。

对于每个点i还要记录cnt[i]=k,表示到i后,i连出的最优的前k条边已被封锁。

每次取出堆顶对应的边u->v(若f[u]已确定直接弹出)则该边为u连出的(除已被封锁的边外)最优的边

若cnt[u]<d,该边必然会被封锁,那么将cnt[u]加1,弹出堆顶

若cnt[u]=d,那么可以确定f[u]=f[v]+w,再用u更新连向u的边,弹出堆顶。

重复这一过程直到确定f[0]的值,该值即为答案。

时间复杂度 O(nlogn)

空间复杂度 O(n)

#include <iostream>#include <cstdio>#include <queue>#include <vector>#include <cstring>using namespace std;typedef long long LL;typedef pair<int, int> ii;const int MAXN = 1e5 + 8;const int MAXM = 1e6 + 8;const int INF = 2e9 + 8;vector<ii> sons[MAXN];int dis[MAXN];int cnt[MAXN];bool vis[MAXN];priority_queue<ii, vector<ii>, greater<ii> > pq;//O(nlogn)inline void ex_dijkstra(int n, int d){memset(vis, false, sizeof vis);int u, v, w, dist, sz, i;while(!pq.empty()){u = pq.top().second;dist = pq.top().first;pq.pop();if(vis[u]) continue;else{if(cnt[u] == d){dis[u] = dist;vis[u] = true;}else{cnt[u]++;continue;}}sz = sons[u].size();for(i = 0; i < sz; i++){v = sons[u][i].first;w = sons[u][i].second;if(dist + w < dis[v]){//dis[v] = d + w;pq.push(ii(dist + w, v));}}}}int main(){#ifdef LOCALfreopen("f.txt", "r", stdin);//freopen("f.out", "w", stdout);int T = 4;while(T--){#endif // LOCALios::sync_with_stdio(false); cin.tie(0);int n, m, k, d, i, u, v, w;//cin >> n;scanf("%d%d%d%d", &n, &m, &k, &d);for(i = 0; i < m; i++){scanf("%d%d%d", &u, &v, &w);sons[u].push_back(ii(v, (int)w));sons[v].push_back(ii(u, (int)w));}for(int i = 0; i <= n; i++){dis[i] = INF;}for(i = 0; i < k; i++){scanf("%d", &u);dis[u] = 0;cnt[u] = d;pq.push(ii(0, u));}ex_dijkstra(n, d);if(dis[0] == INF) puts("-1");else printf("%d\n", dis[0]);#ifdef LOCALwhile(!pq.empty()) pq.pop();memset(cnt, 0, sizeof cnt);for(i = 0; i <= n; i++) sons[i].clear();cout << endl;}#endif // LOCALreturn 0;}

Thank you!

------fromProLights

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。