團體程式設計天梯賽 周遊世界(最短路)
阿新 • • 發佈:2019-02-18
思路: 寫了好多版本, 都是按照點的關係入隊, 不知道怎麼會錯就是看該點是否是換乘點。。。。。後來按照邊的關係入隊之後就過了, dis[ci][si]:源點到si這個站點時,最後經過的一條路線是屬於公司ci的,然後就是記錄兩個資訊:經過的站點數還有換乘的次數, 按照最短路那樣更新就好了。
#include<bits/stdc++.h> const int maxn = 1e2 + 5; const int maxm = 1e4 + 5; const int INF = 1e9 + 10; using namespace std; struct P { int now, las, dis, tot; P() {} P(int n, int l, int d, int t) : now(n), las(l), dis(d), tot(t) {} bool operator < (P p) const { if(dis != p.dis) return dis > p.dis; return tot > p.tot; } }; typedef pair<int, int> pa; int tot[maxn], rec[maxn][maxn]; int n, m, T, kase = 1, num; map<int, int> mp; int vis[maxm]; pa flag[maxn][maxm], dis[maxn][maxm]; int val[maxm]; vector<pa> gx[maxm]; pa sta; int dijkstra(int ss, int st) { if(!ss || !st) return INF; for(int i = 0; i <= num; i++) { for(int j = 0; j <= n; j++) { flag[j][i] = pa(-1, -1); dis[j][i] = pa(INF, INF); } } priority_queue<P> que; for(int i = 0; i < gx[ss].size(); i++) { pa edge = gx[ss][i]; int bel = edge.second; if(!dis[bel][ss].first) continue; dis[bel][ss] = pa(0, 0); que.push(P(bel, ss, 0, 0)); } while(!que.empty()) { P p = que.top(); que.pop(); int c = p.now, s = p.las, di = p.dis, ti = p.tot; if(pa(di, ti) > dis[c][s]) continue; if(s == st) { sta = pa(c, s); return di; } for(int i = 0; i < gx[s].size(); i++) { pa edge = gx[s][i]; int nc = edge.second, ns = edge.first; int nxt_dis = di + 1, nxt_tot = ti + (c != nc); pa nxt(nxt_dis, nxt_tot); if(nxt >= dis[nc][ns]) continue; dis[nc][ns] = nxt; que.push(P(nc, ns, nxt_dis, nxt_tot)); flag[nc][ns] = pa(c, s); } } return INF; } int main() { while(scanf("%d", &n) != EOF) { mp.clear(); int cnt = 1; for(int i = 0; i < maxm; i++) gx[i].clear(); for(int i = 1; i <= n; i++) { scanf("%d", &tot[i]); for(int j = 0; j < tot[i]; j++) { scanf("%d", &rec[i][j]); int x = rec[i][j]; if(!mp.count(x)) mp[x] = cnt++; int id = mp[x]; rec[i][j] = id; val[id] = x; } for(int j = 0; j < tot[i] - 1; j++) { int x = rec[i][j], y = rec[i][j + 1]; gx[x].push_back(pa(y, i)); gx[y].push_back(pa(x, i)); } } num = cnt; int q; scanf("%d", &q); while(q--) { vector<P> ans; vector<pa> vec; int from, to; scanf("%d %d", &from, &to); int fromid = mp[from], toid = mp[to]; int ans1 = dijkstra(fromid, toid); if(ans1 == INF) { printf("Sorry, no line is available.\n"); continue; } printf("%d\n", ans1); while(sta.first != -1) { int x = sta.first, y = sta.second; pa nxt_d = flag[x][y]; vec.push_back(pa(x, val[y])); sta = nxt_d; } int ssz = vec.size(); for(int i = ssz - 1; i >= 0; i--) { int from = i; while(from >= 0 && vec[i].first == vec[from].first) from--; int di = vec[i].first, ql, qr = vec[from + 1].second; if(i == ssz - 1) ql = vec[i].second; else ql = vec[i + 1].second; ans.push_back(P(di, ql, qr, 0)); i = from + 1; } for(int i = 0; i < ans.size(); i++) printf("Go by the line of company #%d from %04d to %04d.\n", ans[i].now, ans[i].las, ans[i].dis); } } return 0; } /** #include<bits/stdc++.h> const int maxn = 1e2 + 5; const int maxm = 1e4 + 5; const int INF = 1e9 + 10; using namespace std; struct P { int now, las, dis; P() {} P(int n, int l, int d) : now(n), las(l), dis(d) {} bool operator < (P p) const { return dis > p.dis; } }; typedef pair<int, int> pa; int tot[maxn], rec[maxn][maxn]; int n, m, T, kase = 1, num; map<int, int> mp; vector<int> G[maxm], pre[maxm]; int vis[maxm]; pa flag[maxn][maxm]; int val[maxm]; int dis[maxn][maxm]; vector<int> gx[maxm]; int bfs1(int s, int t) { if(!s || !t) return INF; for(int i = 0; i <= num; i++) { vis[i] = INF; pre[i].clear(); } vis[s] = 0; queue<int> que; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); for(int i = 0; i < gx[u].size(); i++) { int v = gx[u][i], d = vis[u] + 1; if(vis[v] < d) continue; vis[v] = d; pre[v].push_back(u); que.push(v); } } return vis[t]; } pa sta; void solve(int s, int t, int st) { priority_queue<P> que; for(int i = 0; i < num; i++) { pre[i].push_back(i); for(int j = 0; j <= n; j++) { dis[j][i] = INF; flag[j][i] = pa(-1, -1); } } for(int i = 0; i < G[s].size(); i++) { int c = G[s][i]; que.push(P(c, s, 0)); dis[c][s] = 0; } while(!que.empty()) { P p = que.top(); que.pop(); int c = p.now, u = p.las, di = p.dis; if(di > dis[c][u]) continue; if(u == t) { sta = pa(c, u); return ; } for(int i = 0; i < pre[u].size(); i++) { int v = pre[u][i]; for(int j = 0; j < G[v].size(); j++) { int nc = G[v][j], w; if(c == nc && u == v) continue; if(c != nc && u != v) continue; if(c == nc) w = 0; else w = 1; int nxt_dis = w + di; if(dis[nc][v] <= nxt_dis) continue; dis[nc][v] = nxt_dis; que.push(P(nc, v, nxt_dis)); flag[nc][v] = pa(c, u); } } } } int main() { //freopen("E:\\in.txt", "r", stdin); //freopen("E:\\out1.txt", "w", stdout); while(scanf("%d", &n) != EOF) { mp.clear(); int cnt = 1; for(int i = 0; i < maxm; i++) { G[i].clear(); gx[i].clear(); } for(int i = 1; i <= n; i++) { scanf("%d", &tot[i]); for(int j = 0; j < tot[i]; j++) { scanf("%d", &rec[i][j]); int x = rec[i][j]; if(!mp.count(x)) mp[x] = cnt++; int id = mp[x]; rec[i][j] = id; val[id] = x; G[id].push_back(i); } for(int j = 0; j < tot[i] - 1; j++) { int x = rec[i][j], y = rec[i][j + 1]; gx[x].push_back(y); gx[y].push_back(x); } } num = cnt; int q; scanf("%d", &q); while(q--) { vector<P> ans; vector<pa> vec; int from, to; scanf("%d %d", &from, &to); int fromid = mp[from], toid = mp[to]; int ans1 = bfs1(fromid, toid); if(ans1 == INF) { printf("Sorry, no line is available.\n"); continue; } printf("%d\n", ans1); solve(toid, fromid, ans1); while(sta.first != -1) { int x = sta.first, y = sta.second; pa nxt_d = flag[x][y]; vec.push_back(pa(x, val[y])); sta = nxt_d; } int ssz = vec.size(); for(int i = 0; i < vec.size(); ) { int from = i; while(from < ssz && vec[i].first == vec[from].first) from++; int di = vec[i].first, ql = vec[i].second, qr = vec[from - 1].second; ans.push_back(P(di, ql, qr)); i = from; } for(int i = 0; i < ans.size(); i++) printf("Go by the line of company #%d from %04d to %04d.\n", ans[i].now, ans[i].las, ans[i].dis); } } return 0; } #include<bits/stdc++.h> const int maxn = 1e2 + 5; const int maxm = 1e4 + 5; const int INF = 1e9 + 10; using namespace std; struct P { int now, las, dis, tot; P() {} P(int n, int l, int d, int t) : now(n), las(l), dis(d), tot(t) {} bool operator < (P p) const { if(dis != p.dis) return dis > p.dis; return tot > p.tot; } }; typedef pair<int, int> pa; int tot[maxn], rec[maxn][maxn]; int n, m, T, kase = 1, num; map<int, int> mp; vector<int> G[maxm]; pa flag[maxn][maxm], dis[maxn][maxm]; int val[maxm]; vector<int> gx[maxm]; pa sta; int dijkstra(int s, int t) { if(!s || !t) return INF; //printf("begin : %d end:%d\n", val[s], val[t]); for(int i = 1; i <= num; i++) { for(int j = 1; j <= n; j++) { dis[j][i] = pa(INF, INF); flag[j][i] = pa(-1, -1); } } priority_queue<P> que; for(int i = 0; i < G[s].size(); i++) { int c = G[s][i]; if(!dis[c][s].first) continue; //printf("%d : #%d\n", val[s], c); dis[c][s] = pa(0, 0); que.push(P(c, s, 0, 0)); } while(!que.empty()) { P p = que.top(); que.pop(); int ci = p.now, si = p.las, di = p.dis, ti = p.tot; if(di > dis[ci][si].first || (di == dis[ci][si].first && ti > dis[ci][si].second)) continue; if(si == t) { sta = pa(ci, si); return di; } for(int i = 0; i < gx[si].size(); i++) { int v = gx[si][i]; // printf("%d -> %d\n", val[si], val[v]); for(int j = 0; j < G[v].size(); j++) { int nc = G[v][j], w = (nc != ci); int ws = (si != v); if(ci == nc && si == v) continue; if(ci != nc && si != v) continue; // printf("#%d:%d -> #%d:%d\n", ci, val[si], nc, val[v]); int nxt_dis = di + ws, nxt_tot = ti + w; if(nxt_dis > dis[nc][v].first) continue; if(nxt_dis == dis[nc][v].first && nxt_tot >= dis[nc][v].second) continue; dis[nc][v] = pa(nxt_dis, nxt_tot); flag[nc][v] = pa(ci, si); que.push(P(nc, v, nxt_dis, nxt_tot)); } } } } int main() { while(scanf("%d", &n) != EOF) { mp.clear(); int cnt = 1; for(int i = 0; i < maxm; i++) { G[i].clear(); gx[i].clear(); } for(int i = 1; i <= n; i++) { scanf("%d", &tot[i]); for(int j = 0; j < tot[i]; j++) { scanf("%d", &rec[i][j]); int x = rec[i][j]; if(!mp.count(x)) mp[x] = cnt++; int id = mp[x]; rec[i][j] = id; G[id].push_back(i); val[id] = x; } for(int j = 0; j < tot[i] - 1; j++) { int x = rec[i][j], y = rec[i][j + 1]; //printf("%d <<>> %d\n", val[x], val[y]); gx[x].push_back(y); gx[y].push_back(x); } } num = cnt; for(int i = 1; i < num; i++) gx[i].push_back(i); for(int i = 1; i < num; i++) { //for(int j = 0; j < gx[i].size(); j++) //printf("%d << >> %d\n", val[i], val[gx[i][j]]); } int q; scanf("%d", &q); while(q--) { vector<P> ans; vector<pa> vec; int from, to; scanf("%d %d", &from, &to); int fromid = mp[from], toid = mp[to]; int ans1 = dijkstra(fromid, toid); if(ans1 == INF) { printf("Sorry, no line is available.\n"); continue; } printf("%d\n", ans1); while(sta.first != -1) { int x = sta.first, y = sta.second; pa nxt_d = flag[x][y]; vec.push_back(pa(x, val[y])); sta = nxt_d; } int ssz = vec.size(); for(int i = ssz - 1; i >= 0; i--) { int from = i; while(from >= 0 && vec[i].first == vec[from].first) from--; int di = vec[i].first, ql = vec[i].second, qr = vec[from + 1].second; ans.push_back(P(di, ql, qr, 0)); i = from + 1; } for(int i = 0; i < ans.size(); i++) printf("Go by the line of company #%d from %04d to %04d.\n", ans[i].now, ans[i].las, ans[i].dis); } } return 0; } */