2179: 紧急营救
Description
冷锋在非洲完成任务后回到了狼牙特种作战部队。我们知道在战狼二结尾,冷锋正在北极执行任务,而部队发现了龙小云在c国的消息,让冷锋尽快赶往c国。我们知道现在地球上共有n个国家和地区,编号分别为1,2,3…n。国家与国家之间的可能通航班(可能不止一次),也可能没有通航班。共有m次航班,冷锋已经知道了这m次航班的信息(起点 终点,时间)北极的编号是1,c国的编号是n。
而冷峰身为超级英雄一样的的存在,他有一次将航班的时间降为零的能力。
Input
样例数t(t<=10),接下来又t组样例。 每组样例先输入n , m(n<=1000 , m<=n*(n-1)/2)。
下面m行航班的信息,分别为start , end , time(time <= 100000).
Output
对每组样例,输出冷锋到达c国的最短时间,若不能到达输出 “Impossible”。
Sample Input
3
3 1
1 2 1
4 3
1 2 4
2 3 1
2 4 4
3 3
1 2 100000
2 3 1
1 3 2
Sample Output
Impossible
4
0
题解:
挺好的题 我们可以从起点到终点 这两个点 跑两个最短路 dis1, dis2 记录每个点的最短路
然后就是枚举每一条边 变为0寻找最短路了 公式 min(min(dis1[i]+dis2[j],dis1[j]+dis2[i]),minx)
AC代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define CLR(a,b) memset(a,(b),sizeof(a))
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
const int N = 1e3+10;
int mps[N][N]; //邻接矩阵,表示从->的距离
bool vis[N]; // 标记节点是否被访问'
int dis_1[N], dis_2[N];
int n, m;
void Dijkstra(int s,int dis[])
{
CLR(dis,0); CLR(vis,false);
for(int i = 1;i <= n; i++) dis[i] = mps[s][i];
dis[s] = 0;
vis[s] = true;
int minx, k;
for(int i = 1;i <= n; i++) {
minx = INF;
for(int j = 1;j <= n; j++) {
if(!vis[j] && minx>dis[j]) {
minx = dis[j];
k = j;
}
}
if(minx == INF) break;
vis[k] = true;
for(int j = 1; j <= n; j++) {
if(!vis[j] && dis[j]>dis[k]+mps[k][j]) {
dis[j] = dis[k]+mps[k][j];
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
int x, y, z;
for(int i = 1;i <= n; i++) {
for(int j = 1;j <= n; j++) {
if(i == j) mps[i][j] = 0;
mps[i][j] = INF;
}
}
for(int i = 0; i < m; i++) {
scanf("%d%d%d",&x,&y,&z);
if(z < mps[x][y]) mps[x][y] = mps[y][x] = z;
}
int minx = INF;
Dijkstra(1,dis_1); Dijkstra(n,dis_2);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(mps[i][j]!=INF && i!=j) {
minx = min(min(dis_1[i]+dis_2[j],dis_1[j]+dis_2[i]),minx);
}
}
}
if(minx == INF)
puts("Impossible");
else
printf("%d\n",minx);
}
return 0;
}