zzuli 2179: 紧急营救(有一条边权值可变为0的最短路)

来源:互联网 发布:linux 鸟哥的私房菜 编辑:程序博客网 时间:2024/05/16 08:45

题目链接

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

真的是不想说,这出题人语文怕是白学了,题目描述路线是航班,还有起点,终点,按理说是有向图,然而这个题竟然是无向图,(鉴于出题人已经修改题面,这里就不吐槽这么狠了。)

思路就是先跑出起点1到其他任意点的距离存到dis2里面,然后再跑一下n到其他任意点的距离存到dis1里面,然后再枚举每条边,判断把这条边的权值置为0,是否能让结果更小,由于是无向图,所以对于u-v这条边,res = min(res,dis1[u]+dis2[v],dis1[v]+dis2[u]);

这题还是非常好的,开阔思路,如果这是有向图的话,我们的做法就是同样先跑出1到其他任意点的距离存到dis2里面,然后再把边反向存一下,再跑出任意一个点到n的距离,然后再枚举每条u-v边,即
res = min(res,dis2[u]+dis1[v]);

题目代码如下:

#include<bits/stdc++.h>using namespace std;const int MAX_V = 1010;const int MAX_E = 500010;const int INF = 0x3f3f3f3f;int x[MAX_E],y[MAX_E],z[MAX_E];int dis1[MAX_V],dis2[MAX_V];bool used[MAX_V];struct Edge{    int to;    int cost;}es;vector<Edge> G[MAX_V];int n,m;void spfa(int a_){    fill(dis1+1,dis1+1+n,INF);    memset(used,false,sizeof(used));    dis1[a_] = 0;    queue<int> q;    q.push(a_);used[a_] = true;    while(!q.empty()){        int k = q.front();q.pop();        int len = G[k].size();        for(int i=0;i<len;i++){            es = G[k][i];            if(dis1[es.to] > dis1[k] + es.cost){                dis1[es.to] = dis1[k] + es.cost;                if(!used[es.to]){                    q.push(es.to);                }            }        }        used[k] = false;    }}int main(void){    int t;    scanf("%d",&t);    while(t--){        scanf("%d %d",&n,&m);        for(int i=1;i<=n;i++)            G[i].clear();        for(int i=1;i<=m;i++){            scanf("%d %d %d",&x[i],&y[i],&z[i]);            es.to = y[i];es.cost = z[i];            G[x[i]].push_back(es);            es.to = x[i];            G[y[i]].push_back(es);        }        spfa(1);        for(int i=1;i<=n;i++){            dis2[i] = dis1[i];        }        spfa(n);        int res = INF;        for(int i=1;i<=m;i++){            res = min(res,dis2[x[i]]+dis1[y[i]]);            res = min(res,dis2[y[i]]+dis1[x[i]]);        }        if(res == INF)            printf("Impossible\n");        else            printf("%d\n",res);    }    return 0;}
阅读全文
0 0