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出发,到各个点的最短距离,再从终点n出发,到各个店的最短距离。然后枚举边(i,j)(那个特技相当于拆除一条存在的边),只要这个边存在就拆除,ans = min(ans , dis1[i] + dis2[j]) ;
#include
#include
#include
#include
#include
#define max_n 1000010
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int mapp[1010][1010];
int dis1[1010], dis2[1010];
int head[max_n], dis[max_n];
int t, n, m, cnt = 0;
struct node {
int to;
int next;
int cost;
}edge[max_n];
void addedge(int u, int v, int cot) {
edge[cnt].to = v;
edge[cnt].next = head[u];
edge[cnt].cost = cot;
head[u] = cnt++;
}
void spfa(int x) {
memset(dis, INF, sizeof(dis));
queue<int> q;
dis[x] = 0;
q.push(x);
while(!q.empty()) {
int ant = q.front();
q.pop();
int u = head[ant];
for(int i = u; i != -1; i = edge[i].next) {
int res = dis[ant] + edge[i].cost;
if(res < dis[edge[i].to]) {
dis[edge[i].to] = res;
q.push(edge[i].to);
}
}
}
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d %d", &n, &m);
cnt = 0;
memset(head, -1, sizeof(head));
memset(mapp, INF, sizeof(mapp));
for(int i = 1; i <= n; i++) {
mapp[i][i] = 0;
}
while(m--) {
int p1, p2, cos;
scanf("%d %d %d", &p1, &p2, &cos);
mapp[p1][p2] = mapp[p2][p1] = min(mapp[p1][p2], cos);
addedge(p1, p2, cos);
addedge(p2, p1, cos);
}
spfa(1);
for(int i = 1; i <= n; i++) {
dis1[i] = dis[i];
}
spfa(n);
for(int i = 1; i <= n; i++) {
dis2[i] = dis[i];
}
int ans = INF;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n ;j++) {
if(mapp[j][i] != INF)
ans = min(ans, dis1[i] + dis2[j]);
}
}
if(ans == INF) printf("Impossible\n");
else printf("%d\n", ans);
}
return 0;
}
#include
#include
#include
#include
#define max_n 1010
#define INF 0x3f3f3f3f
using namespace std;
int mapp[max_n][max_n];
int dis1[max_n], dis2[max_n], dis[max_n];
int vis[max_n];
int n, m, t;
void dij(int x) {
memset(vis, 0, sizeof(vis));
memset(dis, INF, sizeof(dis));
vis[x] = 1;
for(int i = 1; i <= n; i++)
dis[i] = mapp[x][i];
for(int i = 2; i<= n; i++) {
int minn = INF, id;
for(int j = 1; j <= n; j++) {
if(!vis[j] && minn > dis[j]) {
minn = dis[j];
id = j;
}
}
vis[id] = 1;
for(int j = 1; j <= n; j++) {
int ans = dis[id] + mapp[id][j];
if(!vis[j] && ans < dis[j]) {
dis[j] = ans;
}
}
}
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d %d", &n, &m);
memset(mapp, INF, sizeof(mapp));
for(int i = 1; i <= n; i++) {
mapp[i][i] = 0;
}
while(m--) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
mapp[a][b] = mapp[b][a] = min(mapp[a][b], c);
}
dij(1);
for(int i = 1; i<= n; i++) {
dis1[i] = dis[i];
}
dij(n);
for(int i = 1; i <= n; i++) {
dis2[i] = dis[i];
}
int ans = INF;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n ;j++) {
if(mapp[j][i] != INF)
ans = min(ans, dis1[i] + dis2[j]);
}
}
if(ans == INF) printf("Impossible\n");
else printf("%d\n", ans);
}
return 0;
}