热爱工作的蒜蒜
众所周知,蒜蒜是一名热爱工作的好员工,他觉得时间就是金钱,做事情总是争分夺秒。
这天晚上,蒜蒜一个人去吃晚饭。不巧的是,吃完饭以后就开始下雨了,蒜蒜并没有带雨伞出来。但是蒜蒜热爱工作,工作使他快乐,他要尽快赶回去写代码。
蒜蒜的公司在中关村,中关村这边地形复杂,有很多天桥、地下通道和马路交错在一起。其中,地下通道是可以避雨的,天桥和马路都没办法避。可以把中关村抽象成为 n 个点的地图(顶点编号为 1 到 n),其中有 m1 条地下通道,有 m2 条马路或者天桥,其中地下通道的长度为 1。蒜蒜吃饭的地方在 1 点,公司在 n 点。当然,蒜蒜虽然爱工作心切,但是他更不想淋很多雨,同时也不想浪费很多时间。于是他折中了一下——在保证他回到公司所走的路程总和小于等于 L 的情况下,他希望淋雨的路程和尽量的少。
请你赶紧帮热爱工作的蒜蒜规划一条路径吧,不要再让他浪费时间。
输入格式
第一行输入测试组数 T(1 <= T <= 20)T(1≤T≤20)。
接下来 TT 组数据。
每一组数据的第一行输入四个整数 n(2≤n≤100),m1(0≤m1≤50)m2(0≤m2≤5000),L(1≤L≤10^8)。
接下里 m1 行,每行输入两个整数 a,b(1≤a,b≤n),表示 aa 和 bb 之间有一条地下通道。
接下里 m2 行,每行输入三个整数 u,v(1≤u,v≤n),c(1≤c≤106),表示 u 和 v 之间有一条长度为 c 的马路或者天桥。
所有路径都是双向的。
输出格式
对于每组数据,如果有满足要求的路径,输出一个整数,表示淋雨的路程长度,否则输出 -1。
样例输入
3 4 2 2 6 1 2 2 3 1 4 5 3 4 4 4 2 2 5 1 2 2 3 1 4 5 3 4 4 4 2 2 4 1 2 2 3 1 4 5 3 4 4
样例输出
4 5 -1
题目来源
求最段路径,每次求完一个淋雨的路后就遍历全部的路。
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 using namespace std; 4 const int N = 110; 5 int t, n, m1, m2, l; 6 int g[N][N], vis[N], dp[N], dis[N]; 7 typedef pair<int, int> P; 8 vector<P> vs[N]; 9 void init() { 10 for(int i = 0; i <= n; i ++) { 11 vs[i].clear(); 12 dp[i] = dis[i] = INF; 13 } 14 memset(g, 0, sizeof(g)); 15 memset(vis, 0, sizeof(vis)); 16 } 17 void dij() { 18 queue<int> que; 19 que.push(1); vis[1] = 1; 20 dp[1] = dis[1] = 0; 21 while(!que.empty()) { 22 int u = que.front();que.pop(); 23 vis[u] = 0; 24 for(int i = 0; i < vs[u].size(); i ++) { 25 int v = vs[u][i].first, w = vs[u][i].second; 26 if(dp[v] > dp[u] + w && dis[u] + w <= l) { 27 dp[v] = dp[u] + w; 28 dis[v] = dis[u] + w; 29 if(!vis[v]) { 30 vis[v] = 1; 31 que.push(v); 32 } 33 } 34 } 35 for(int i = 1; i <= n; i ++) { 36 if(g[u][i]) { 37 if(dp[i] > dp[u] && dis[u] + 1 <= l) { 38 dp[i] = dp[u]; 39 dis[i] = dis[u] + 1; 40 if(!vis[i]) { 41 vis[i] = 1; 42 que.push(i); 43 } 44 } 45 } 46 } 47 } 48 if(dp[n] <= l && dis[n] <= l) cout << dp[n] << endl; 49 else cout << -1 << endl; 50 } 51 int main() { 52 cin >> t; 53 while(t--) { 54 int u, v, w; 55 cin >> n >> m1 >> m2 >> l; 56 init(); 57 for(int i = 1; i <= m1; i ++) { 58 cin >> u >> v; 59 g[u][v] = g[v][u] = 1; 60 } 61 for(int i = 1; i <= m2; i ++) { 62 cin >> u >> v >> w; 63 vs[u].push_back(P(v, w)); 64 vs[v].push_back(P(u, w)); 65 } 66 dij(); 67 } 68 return 0; 69 }