Light oj-1002 - Country Roads,迪杰斯特拉变形,不错不错~~
| Time Limit: 3 second(s) | Memory Limit: 32 MB |
I am going to my home. There are many cities and many bi-directional roads between them. The cities are numbered from 0 to n-1 and each road has a cost. There are m roads. You are given the number of my
city t where I belong. Now from each city you have to find the minimum cost to go to my city. The cost is defined by the cost of the maximum road you have used to go to my city.

For example, in the above picture, if we want to go from 0 to 4, then we can choose
1) 0 - 1 - 4 which costs 8, as 8 (1 - 4) is the maximum road we used
2) 0 - 2 - 4 which costs 9, as 9 (0 - 2) is the maximum road we used
3) 0 - 3 - 4 which costs 7, as 7 (3 - 4) is the maximum road we used
So, our result is 7, as we can use 0 - 3 - 4.
Input
Input starts with an integer T (≤ 20), denoting the number of test cases.
Each case starts with a blank line and two integers n (1 ≤ n ≤ 500) and m (0 ≤ m ≤ 16000). The next m lines, each will contain three integers u, v, w (0 ≤ u, v < n, u ≠ v, 1 ≤ w ≤ 20000) indicating
that there is a road between u and v with cost w. Then there will be a single integer t (0 ≤ t < n). There can be multiple roads between two cities.
Output
For each case, print the case number first. Then for all the cities (from 0 to n-1) you have to print the cost. If there is no such path, print 'Impossible'.
Sample Input |
Output for Sample Input |
|
2 5 6 0 1 5 0 1 4 2 1 3 3 0 7 3 4 6 3 1 8 1 5 4 0 1 5 0 1 4 2 1 3 3 4 7 1 |
Case 1: 4 0 3 7 7 Case 2: 4 0 3 Impossible Impossible |
Note
Dataset is huge, user faster I/O methods.
学最短路这么久了竟然漏了这个大水题,哈哈哈哈~~
做这道题的时候分析了一下样例,题意就是求从t点出发到所有点的所有路径的最小值,千万注意那句话,而这个最小值既是说一整条路径的最长的那条,所有路径中最长的一条再取最短的那条,貌似表述很混乱,不过看样例就可以明白了,那么怎么做呢;
很明显是一个最短路的变形题,万变不离其宗,方法任意,这里就用dijsktra算法吧,如果从t点出发到不了某个点那么就输出”Impossible“,我们又怎么知道这个点与t点是否联通呢,很简单,用并查集判断一下就好了;
至于dij算法怎么变形呢,我们就用d[i]来储存从t点出发到i点所有可能路径中的所有最长的线段中最短的那条(本质还是其最短路嘛
);再用dijsktra模板打上去,注意在求某点的d[i]时我们需要把d[i]=min(d[i],d[x]+w[x][i])改成d[i]=min(d[i],max(d[x],w[x][i]);前提是x到i之间存在一条路径;这样不就巧妙地解决了问题;具体来看代码:
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=500+10;
int u,v,ww,t,t1,n,m,x,vis[N],f[N],w[N][N],d[N];
int find(int x)
{
return f[x]==-1?x:f[x]=find(f[x]);
}
void dijsktra()
{
memset(vis,0,sizeof(vis));
memset(f,-1,sizeof(f));
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
w[i][j]=i==j?0:INF;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&u,&v,&ww);
w[u][v]=w[v][u]=w[u][v]==INF?ww:min(w[u][v],ww);
int xx=find(u);
int yy=find(v);
if(xx!=yy)
f[xx]=yy;//将所有与定点联通的点连接起来;
}
scanf("%d",&x);
for(int i=0; i<n; i++) d[i]=i==x?0:INF;
for(int i=0; i<n; i++)
{
int xx=0,m=INF;
for(int j=0; j<n; j++)
if(!vis[j]&&d[j]<=m)
m=d[xx=j];
vis[xx]=1;
for(int j=0; j<n; j++)
if(!vis[j]&&w[xx][j]!=INF)
d[j]=min(d[j],max(d[xx],w[xx][j]));
}
printf("Case %d:\n",t1-t);
int xx=find(x);
for(int i=0; i<n; i++)
{
if(find(i)==xx)//如果联通则输出;
printf("%d\n",d[i]);
else
printf("Impossible\n");
}
}
int main()
{
scanf("%d",&t);
t1=t;
while(t--)
{
dijsktra();
}
return 0;
}
后来发现,其实可以不用并查集的,因为如果与T点不连通则它们之间不存在路径,则距离为INF,所以输出判断一下即可: 代码看起来很短的样子,就是喜欢用最简洁的方法解决最复杂的问题
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=500+10;
int u,v,ww,t,t1,n,m,x,vis[N],w[N][N],d[N];
void dijsktra()
{
memset(vis,0,sizeof(vis));
for(int i=0; i<n; i++) d[i]=i==x?0:INF;
for(int i=0; i<n; i++)//注意d[i]储存的值的含义;
{
int xx=0,m=INF;
for(int j=0; j<n; j++)
if(!vis[j]&&d[j]<=m)
m=d[xx=j];说明到xx点的最短路已经求出来了;
vis[xx]=1;
for(int j=0; j<n; j++)
if(!vis[j]&&w[xx][j]!=INF)//说明xx与j点之间存在通路;
d[j]=min(d[j],max(d[xx],w[xx][j]));//一条可能路径的最长的那条与其他路径的最长的那条进行比较;
}
printf("Case %d:\n",t1-t);
for(int i=0; i<n; i++)
{
if(d[i]!=INF)//如果不连通则之间的路长为INF,以此为判断依据;
printf("%d\n",d[i]);
else
printf("Impossible\n");
}
}
int main()
{
scanf("%d",&t);
t1=t;
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
w[i][j]=i==j?0:INF;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&u,&v,&ww);
w[u][v]=w[v][u]=w[u][v]==INF?ww:min(w[u][v],ww);
}
scanf("%d",&x);
dijsktra();
}
return 0;
}
完美!!! 如有更好的方法或者思路,恭请指教!!
Light oj-1002 - Country Roads,迪杰斯特拉变形,不错不错~~的更多相关文章
- Light oj 1002 Country Roads (Dijkstra)
题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1002 题目描述: 有n个城市,从0到n-1开始编号,n个城市之间有m条边,中 ...
- 1002 - Country Roads(light oj)
1002 - Country Roads I am going to my home. There are many cities and many bi-directional roads betw ...
- PAT 1087 All Roads Lead to Rome[图论][迪杰斯特拉+dfs]
1087 All Roads Lead to Rome (30)(30 分) Indeed there are many different tourist routes from our city ...
- 迪杰斯特拉算法——PAT 1003
本文主要是将我对于我对于迪杰斯特拉算法的理解写出来,同时通过例题来希望能够加深对于算法的理解,其中有错误的地方希望大家指正. 迪杰斯特拉算法 我将这个算法理解成一个局部到整体的算法,这个方法确实越研究 ...
- hdoj-2066-一个人的旅行(迪杰斯特拉)
一个人的旅行 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 3339 In Action(迪杰斯特拉+01背包)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=3339 In Action Time Limit: 2000/1000 MS (Java/Others) ...
- hdu 1595 find the longest of the shortest(迪杰斯特拉,减去一条边,求最大最短路)
find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others) Memory Limit: 32768/32768 ...
- hdu 3339 In Action(迪杰斯特拉+01背包)
In Action Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- Bumped!【迪杰斯特拉消边、堆优化】
Bumped! 题目链接(点击) Peter returned from the recently held ACM ICPC World Finals only to find that his r ...
随机推荐
- 模拟 hihoCoder 1177 顺子
题目传送门 /* 模拟:简单的照着规则做就可以了,把各种情况考虑到,虽然比赛写的丑了点,但能1Y还是很开心的:) */ #include <cstdio> #include <cst ...
- 467 Unique Substrings in Wraparound String 封装字符串中的独特子字符串
详见:https://leetcode.com/problems/unique-substrings-in-wraparound-string/description/ C++: class Solu ...
- python的des和3des加解密
1.加密: pyDes.des(key, [mode], [IV], [pad], [padmode]) pyDes.triple_des(key, [mode], [IV], [pad], [pad ...
- React Native for Android 学习
前言 Facebook 在2015.9.15发布了 React Native for Android,把 JavaScript 开发技术扩展到了移动Android平台.基于React的React Na ...
- [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...
- Unity笔记(4)自学第四、五天
主要是移动脚本和2个技能的脚本编写. 首先是移动的脚本: using System.Collections; using System.Collections.Generic; using Unity ...
- 什么是BDD?
BDD是TDD的一种衍生,通过特定的BDD框架,用自然语言或类自然语言,按照编写用户故事或者用户用例的方式,以功能使用者的视角,描述并编写测试用例. BDD源于TDD并优于测试驱动开发. 之所以说BD ...
- 从0开始搭建SQL Server 2012 AlwaysOn 第三篇(安装数据,配置AlwaysOn)
这一篇是从0开始搭建SQL Server 2012 AlwaysOn 的第三篇,这一篇才真正开始搭建AlwaysOn,前两篇是为搭建AlwaysOn 做准备的 操作步骤: 1.安装SQL server ...
- HDU_1856_带权并查集
有10000000个同学,他们之间可能是直接朋友或者间接朋友,问最大的朋友圈有多少人. 一直觉得10000000的数组开不了,用map优化了一下,结果能开,且10000000也不会超时... #inc ...
- laravel socialite微信登录注意
在token没有过期之前,重新走登录流程时会跳过callback,即不再重新登录,除了删除了客户端的token
