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 ...
随机推荐
- [poj3744] Scout YYF I【概率dp 数学期望】
传送门:http://poj.org/problem?id=3744 令f(i)表示到i,安全的概率.则f(i) = f(i - 1) * p + f(i - 2) * (1 - p),若i位置有地雷 ...
- 二分+树状数组/线段树(区间更新) HDOJ 4339 Query
题目传送门 题意:给两串字符串,操作1:替换其中一个字符串的某个位置的字符 操作2:查询从p开始相等的最长连续长度 分析:树状数组可以维护一个区间内公共长度(连续)的情况,查询时用二分查找最远的端点即 ...
- 题解报告:hdu 2057 A + B Again
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2057 问题描述 我们的HDOJ必须有许多A + B问题,现在又有新的问题出现. 给你两个十六进制整数, ...
- MFC显示文本文档 分类: MFC 2014-12-30 10:03 457人阅读 评论(1) 收藏
新建基于对话框的MFC应用程序.资源视图的对话框上添加编辑框(Edit Control)和按钮(Button), 将编辑框属性:Mutiline.Auto HScroll.Auto VScroll设为 ...
- pycharm的使用小技巧111
如果你想快速敲出if __name__ == '__main__':只需你敲个main 然后回车就ok了 import和from xx模块 import *的区别是前者使用时要加模块名加点,后者可以直 ...
- D. Green and Black Tea 贪心 + 构造
http://codeforces.com/contest/746/problem/D 首先说下一定是NO的情况. 假设a > b 那么,b最多能把a分成b + 1分,如果每份刚好是k的话,那么 ...
- 【深入.NET平台】浅谈.NET Framework基元类型
什么是基元类型? 初学者可能很少听说过这个名词,但是平时用得最多的肯定是基元类型.先看下面两行代码: System.Int32 a = ; ; 上面两行代码都表示声明一个int类型的变量,但在平时写 ...
- Caused by: javax.el.PropertyNotFoundException: Property 'product' not found on type java.lang.String
今天在JSP利用EL表达式取值报了 "javax.el.PropertyNotFoundException”,经过debug和打印将问题定位到这段代码: HTML应该是没啥问题,看提示在ja ...
- DeltaFish 选题报告总结
选题结果:校园物资流动系统 报告地点:3A101 会议时间:16:00 ~ 18:00 与会人员:软工小组全体成员 请假人员:无 缺席人员:无 报告人:陈志锴 一.报告内容总结 1.产品功能 针对校 ...
- Java基础知识强化98.01:Jsp和servlet有什么区别
1. Jsp和servlet有什么区别 首先你先要弄懂什么是servlet,servlet是在服务器端执行的java程序,只不过它有专门的一套规则(就是我们平常所说的api):jsp说得简单点就是用另 ...
