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,迪杰斯特拉变形,不错不错~~的更多相关文章

  1. Light oj 1002 Country Roads (Dijkstra)

    题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1002 题目描述: 有n个城市,从0到n-1开始编号,n个城市之间有m条边,中 ...

  2. 1002 - Country Roads(light oj)

    1002 - Country Roads I am going to my home. There are many cities and many bi-directional roads betw ...

  3. 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 ...

  4. 迪杰斯特拉算法——PAT 1003

    本文主要是将我对于我对于迪杰斯特拉算法的理解写出来,同时通过例题来希望能够加深对于算法的理解,其中有错误的地方希望大家指正. 迪杰斯特拉算法 我将这个算法理解成一个局部到整体的算法,这个方法确实越研究 ...

  5. hdoj-2066-一个人的旅行(迪杰斯特拉)

    一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  6. HDU 3339 In Action(迪杰斯特拉+01背包)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=3339 In Action Time Limit: 2000/1000 MS (Java/Others) ...

  7. 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 ...

  8. hdu 3339 In Action(迪杰斯特拉+01背包)

    In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. Bumped!【迪杰斯特拉消边、堆优化】

    Bumped! 题目链接(点击) Peter returned from the recently held ACM ICPC World Finals only to find that his r ...

随机推荐

  1. 构造 HDOJ 5400 Arithmetic Sequence

    题目传送门 题意:问有多少个区间,其中存在j使得ai + d1 == ai+1(i<j) && ai + d2 == ai+1 (i>j) 构造:用c1[i], c2[i] ...

  2. PWA之serviceWorker应用

    1.serviceWorker介绍service worker是一段运行在浏览器后台的JavaScript脚本,在页面中注册并安装成功后,它可以拦截和处理网络请求,实现缓存资源并可在离线时响应用户的请 ...

  3. 使用mysql实现mybatis的分页效果

    1.mybatis.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configur ...

  4. AJPFX关于面向对象中的对象初始化整理,综合子父类、代码块等等

    今天总结了一下子父类当中含有静态代码块.代码块.构造函数.成员变量.子类复写父类方法时子类的初始化过程,把思路理清一下 class Fu { //父类成员变量 private int num = 3; ...

  5. 04全志R58平台编译内核需要选择的配置

    04全志R58平台编译内核需要选择的配置 2018/11/6 14:19 版本:V1.0 开发板:SC5806 1.系统编译:(略) 每次系统编译/内核的时候都需要选3次N: * * Xtables ...

  6. Node.js——异步上传文件

    前台代码 submit() { var file = this.$refs.fileUpload.files[0]; var formData = new FormData(); formData.a ...

  7. 【译】x86程序员手册34-9.7错误代码

    9.7 Error Code 错误代码 With exceptions that relate to a specific segment, the processor pushes an error ...

  8. CREATE SEQUENCE - 创建一个新的序列发生器

    SYNOPSIS CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ] [ MINVALUE minvalu ...

  9. ascii - 在八进制,十进制,十六进制中的 ASCII 字符集编码

    描述 ASCII 是美国对于信息交换的标准代码,它是7位码,许多8位码(比如 ISO 8859-1, Linux 的默认字符集)容纳 ASCII 作为它们的下半部分.对应的国际 ASSII 是 ISO ...

  10. CAD参数绘制线型标注(网页版)

    主要用到函数说明: _DMxDrawX::DrawDimRotated 绘制一个线型标注.详细说明如下: 参数 说明 DOUBLE dExtLine1PointX 输入第一条界线的起始点X值 DOUB ...