codevs 3971 航班
Posted ACforever
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 3971 航班相关的知识,希望对你有一定的参考价值。
题目描述 Description
B 国有N 座城市,其中1 号是这座国家的首都。
N 座城市之间有M 趟双向航班。i 号点的转机次数定义为:从1 号点到i ,最少需要转机几 次。如果1 根本无法到达i ,那么i 点的转机次数是无穷大。
由于天气原因,有些航班会被取消。
一趟航班的取消是可容忍的,仅当这趟航班取消之后,2..N 每个点的转机次数不变或者只 增加了1。
现在kAc 想知道,哪些航班的取消是可容忍的?
如果这样的航班不存在,输出一行 “hehe”(不含引号)
输入描述 Input Description
第一行两个正整数N, M
接下来M 行每行两个正整数a, b。表示当前这趟航班的两端是a,b 两座城市 ,保证a 不等于b ,且同一对a, b 只会出现一次。
输出描述 Output Description
若干整数,从小到大排序,表示所有的可容忍取消的航班序号。
样例输入 Sample Input
5 6
1 2
1 3
1 4
3 4
2 5
3 5
样例输出 Sample Output
2
3
4
5
6
数据范围及提示 Data Size & Hint
如果1、2 两座城市间的航班被取消,2 号城市到首都原本需要0 次转机(有直达飞机) ,现
在需要先到5 ,再到3 ,再到1 ,转机2 次。这是不可忍受的。
对于40% :N, M<=500
对于70% :N<=500 M <= 50000
对于100% :N, M<=200000
保证初始给定图中所有点的转机次数不是无穷大。
这其实应该叫次短路,每次改一个点
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std; #define fr(x, E) for (__typeof(E.begin()) x = E.begin(); x != E.end(); x++) //first ,second,指的是vector中定义的第几个元素 #define FR first #define SC second #define MP make_pair #define PB push_back #define PII pair<int, int> #define LL long long #define ALL(x) x.begin(), x.end() #define SZ(x) ((int)(x).size()) const int MAXN = 1000001; vector<PII> e[MAXN];//存储边,和第航线序号 int n, m; int from[MAXN], vis[MAXN], dis[MAXN]; bool isok[MAXN]; int main() { freopen("flight2.in", "r", stdin); freopen("flight.out", "w", stdout); scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++){ int a, b; scanf("%d%d", &a, &b); e[a].PB(MP(b, i)); e[b].PB(MP(a, i)); } static queue<int> Q;//宽搜各个顶点到首都的转机次数。 Q.push(1); vis[1] = true;//首都1入队列; while(SZ(Q)){//队列非空 int x = Q.front(); Q.pop(); fr(it, e[x])//和队首顶点关联的每个顶点 if (!vis[it->FR]){//如果没入队列则入队列 vis[it->FR] = true; dis[it->FR] = dis[x] + 1; from[it->FR] = it->SC;//记录最短路径航线 Q.push(it->FR); } } bool ok = true; for (int i = 2; i <= n; i++){ bool nok = true; //假设对应最短路不可以替换 fr(it, e[i])//遍历顶点i的每个关联顶点 , //如果存在不在最短路径上,而且距离不超过当前距离的代替顶点 , if (it->SC != from[i] && dis[it->FR] <= dis[i]) nok = false;//那么,此顶点对应的最短路径这条航线是可以替换的。 isok[from[i]] = nok; } bool ex = false; for (int i = 1; i <= m; i++) if (!isok[i]){ printf("%d\n", i); ex = true; } if (!ex) puts("hehe"); }
以上是关于codevs 3971 航班的主要内容,如果未能解决你的问题,请参考以下文章
UVALive 3971 Assemble(模拟 + 二分)