思路: 写了好多版本, 都是按照点的关系入队, 不知道怎么会错就是看该点是否是换乘点。。。。。后来按照边的关系入队之后就过了, 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;
}
*/