ZZULIoj 2179: 紧急营救 ( 最短路

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  
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;
}

你可能感兴趣的:(online,judge,Others,图论,最短路)