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 ...
随机推荐
- 字符串处理 Codeforces Round #285 (Div. 2) B. Misha and Changing Handles
题目传送门 /* 题意:给出一系列名字变化,问最后初始的名字变成了什么 字符串处理:每一次输入到之前的找相印的名字,若没有,则是初始的,pos[m] 数组记录初始位置 在每一次更新时都把初始pos加上 ...
- 题解报告:hdu 1032 The 3n + 1 problem(克拉兹问题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1032 Problem Description Problems in Computer Science ...
- ACM_求N^N的最高位数
Leftmost Digit Time Limit: 2000/1000ms (Java/Others) Problem Description: 给定一个正整数N,你应该输出N ^ N的最左边的数字 ...
- 动态链接库(DLL) 分类: c/c++ 2015-01-04 23:30 423人阅读 评论(0) 收藏
动态链接库:我们经常把常用的代码制作成一个可执行模块供其他可执行文件调用,这样的模块称为链接库,分为动态链接库和静态链接库. 对于静态链接库,LIB包含具体实现代码且会被包含进EXE中,导致文件过大, ...
- ubu下编译安装php7
第一步: 安装依赖库zlib.libpng.freetype.jpegsrc.libxml2.libgd.freetds.mhash.libmcrypt.mcrypt(依赖于mhash和libmcry ...
- h5学习-css3的一些内容整理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Oracle本地动态 SQL
本地动态 SQL 首先我们应该了解什么是动态 SQL,在 Oracle数据库开发 PL/SQL块中我们使用的 SQL 分为:静态 SQL语句和动态 SQL语句.所谓静态 SQL指在 PL/SQL块中使 ...
- SpringBoot_自定义配置属性
@ConfigurationProperties 在aplication.properties 中添加如下一段配置: mysql.jdbcName=com.mysql.jdbc.Driver mysq ...
- 图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用
图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用 传输层必须指出这个具体的程序,为了实现这一功能,使用端口号这样一种识别码.根据端口号,就可以识别在传输层上一层的应用程 ...
- 解决QTreeView不能设置列宽的问题
转载请注明出处:http://www.cnblogs.com/dachen408/p/7206738.html 设置model之前: ui.treeView->setColumnWidth(0, ...