1. 程式人生 > >團體程式設計天梯賽 周遊世界(最短路)

團體程式設計天梯賽 周遊世界(最短路)

思路: 寫了好多版本, 都是按照點的關係入隊, 不知道怎麼會錯就是看該點是否是換乘點。。。。。後來按照邊的關係入隊之後就過了, 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;
}
*/