/* 好了好久才把SPAF 看懂了,而且不用了,真的好纠结的 原来就一句话的问题,都是把算法混淆了,SPAF开的只要是queue就可以了 其实不要priority_queued 的 */ #include <iostream>//29 悔惜晟 218MS 7840K 3635B C++ 2010-07-14 18:04:13 #include <cstdio> #include <queue> #include <cstring> using namespace std; const int N = 1005; const int INF = 0x7f7f7f7f; int dis[N]; bool hash[N]; bool visit[N]; struct node { int x; int dis; int high; struct node *next; node () { next = NULL; } }; node *map[N], vex[N]; inline void Init() { //map = new node[N]; for(int i = 0; i < N; i++) { //map[i] = &vex[i]; map[i] = new node; //map[i]->next = NULL; } } inline void creat(int x, int y, int dis, int high) { node *p; p = new node; p->x = y; p->dis = dis; p->high = high; p->next = map[x]->next; map[x]->next = p; } struct In { int x; int dis; }; bool SPAF(int st, int en, int h) { queue<In> Q; memset(dis, 0x7f, sizeof(dis)); memset(hash, false ,sizeof(hash)); In P, M; //prev, next M.x = st; M.dis = 0; hash[st] = true;//标记进入队列的点为true dis[st] = 0; Q.push(M); while(!Q.empty()) { P = Q.front(); Q.pop(); hash[P.x] = false;//表示改点不在对列中 //map[P.x] = &vex[P.x]; node *r; r = map[P.x]->next; for(; r != NULL; r = r->next) { if( dis[P.x] + r->dis < dis[r->x] && ( h <= r->high || r->high == -1)) { dis[r->x] = dis[P.x] + r->dis; M.dis = dis[r->x]; M.x = r->x; if(!hash[r->x])//不在队列中的点当松弛过了就标记true { hash[r->x] = true; Q.push(M); } } } } if(dis[en] != INF) return true; else return false; } struct Node { int x; int dis; friend bool operator < (Node a, Node b) { return a.dis > b.dis; } }; /* void BFS(int st, int n) { priority_queue<Node> Q; Node P, M; memset(hash, false, sizeof(hash)); memset(dis, 0x7f, sizeof(dis)); map[st] = &vex[st]; node *p; p = map[st]->next; for(; p != NULL; p = p->next) { M.dis = p->dis; M.x = p->x; dis[p->x] = p->dis; Q.push(M); } hash[st] = true; while(!Q.empty()) { P = Q.top(); Q.pop(); hash[P.x] = true; map[P.x] = &vex[P.x]; p = map[P.x]->next; for(; p != NULL; p = p->next) { if(!hash[p->x] && P.dis + p->dis < dis[p->x]) { dis[p->x] = P.dis + p->dis; M.dis = dis[p->x]; M.x = p->x; Q.push(M); } } } } */ int main() { int m, n; int t = 1; while(scanf("%d %d", &n, &m) != EOF) { int a, b, hig, len; if(n == 0 && m == 0) break; if (t != 1) { puts(""); } Init(); while(m--) { scanf("%d %d %d %d", &a, &b, &hig, &len); { //cost[a][b] = cost[b][a] = len; creat(a, b, len, hig); creat(b, a, len, hig); //high[a][b] = high[b][a] = hig; } } scanf("%d %d %d", &a, &b, &hig); int Low, High, mid; Low = 1; High = hig; int hui = hig; int xi = INF; while(Low <= High) { mid = (Low + High) / 2; if(SPAF(a, b, mid)) { //High = mid - 1; Low = mid + 1; hui = mid; xi = dis[b]; } else { High = mid - 1; //Low = mid + 1; } } printf("Case %d:/n", t++); if(xi != INF) { printf("maximum height = %d/n", hui); printf("length of shortest route = %d/n", xi); } else { printf("cannot reach destination/n"); } } } /* int main() { int t, s, d; while(scanf("%d %d %d", &t, &s, &d) != EOF) { int a, b, di; int n = -INF; Init(); while(t--) { scanf("%d %d %d", &a, &b, &di); if(a > n) n = a; if(b > n) n = b; creat(a, b, di); creat(b, a, di); } while(s--) { scanf("%d", &a); creat(0, a, 0); creat(a, 0, 0); } while(d--) { scanf("%d", &b); creat(b, n + 1, 0); creat(n + 1, b, 0); } SPAF(0); printf("%d/n", dis[n + 1]); } return 0; } */ #include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; const int MAX = 0x3fffffff; const int N = 1005; int high[N][N]; int cost[N][N]; int dis[N]; //int pat[N]; bool hash[N]; int n; bool Dijsktra(int s, int e, int h) { for(int i = 1; i <= n; i++) { dis[i] = cost[s][i]; if (high[s][i] < h) { dis[i] = MAX; } } memset(hash, false, sizeof(hash)); hash[s] = true; dis[s] = 0; for(int i = 1; i < n; i++) { int d = MAX; int k = s; //int t = - MAX; for(int j = 1; j <= n; j++) { if(dis[j] < d && !hash[j])//&& (h <= high[s][j] || high[s][j] == -1) ) { d = dis[j]; k = j; //t = pat[j]; } } if (d == MAX) { break; } hash[k] = true; for(int j = 1; j <= n; j++) { if(!hash[j] && dis[k] + cost[k][j] < dis[j] && (h <= high[k][j] || high[k][j] == -1) ) { dis[j] = cost[k][j] + dis[k]; // if(h > high[k][j]) // dis[j] = MAX; } //if() } } if(dis[e] != MAX) return true; else return false; } struct node { int dis; int num; friend bool operator < (node a, node b) { return a.dis > b.dis; } }; bool BFS(int s, int e, int h)// 2567034 2010-07-03 00:20:13 Accepted 2962 609MS 8216K 3028 B C++ 悔惜晟 { priority_queue<node> Q; node P, N; memset(hash, false, sizeof(hash)); for(int i = 1; i <= n; i++) { dis[i] = cost[s][i]; if (high[s][i] < h && high[s][i] != -1) { dis[i] = MAX; } } for(int i = 1; i <= n; i++) { if((high[s][i] >= h || high[s][i] == -1) && cost[s][i] < MAX) { N.dis = cost[s][i]; N.num = i; Q.push(N); } } while(!Q.empty()) { P = Q.top(); Q.pop(); hash[P.num] = true; if(hash[e]) return true; for(int i = 1; i <= n; i++) { if(!hash[i] && P.dis + cost[P.num][i] < dis[i] && (high[P.num][i] >= h || high[P.num][i] == -1)) { dis[i] = N.dis = P.dis + cost[P.num][i]; N.num = i; Q.push(N); } } } return false; } int main() { int m; int t = 1; while(scanf("%d %d", &n, &m) != EOF) { int a, b, hig, len; if(n == 0 && m == 0) break; if (t != 1) { puts(""); } for(int i = 1; i < N; i++) for(int j = 1; j < N; j++) { cost[i][j] = MAX; } while(m--) { scanf("%d %d %d %d", &a, &b, &hig, &len); { cost[a][b] = cost[b][a] = len; high[a][b] = high[b][a] = hig; } } scanf("%d %d %d", &a, &b, &hig); int Low, High, mid; Low = 0; High = hig; int hui = hig; int xi = MAX; while(Low <= High) { mid = (Low + High) / 2; //if(Dijsktra(a, b, mid)) if(BFS(a, b, mid)) { //High = mid - 1; Low = mid + 1; hui = mid; xi = dis[b]; } else { High = mid - 1; //Low = mid + 1; } } printf("Case %d:/n", t++); if(xi != MAX) { printf("maximum height = %d/n", hui); printf("length of shortest route = %d/n", xi); } else { printf("cannot reach destination/n"); } } }