团体程序设计天梯赛 周游世界(最短路)

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Python八十天环游世界》是一本以Python编程语言为主题的书籍,它通过一系列有趣的项目和挑战,帮助读者掌握Python的各种应用和技巧。这本书的目标是帮助读者在八十天内通过实践来提高他们的Python编程能力,并且了解Python在不同领域的应用。 这本书通常会涵盖以下内容: 1. Python基础知识:包括变量、数据类型、条件语句、循环语句等基本概念和语法。 2. 函数和模块:介绍如何定义和使用函数,以及如何使用Python的模块来组织代码。 3. 文件操作:学习如何读写文件,以及如何处理CSV、JSON等常见文件格式。 4. 网络编程:了解如何使用Python进行网络通信,包括HTTP请求、Socket编程等。 5. 数据库操作:介绍如何使用Python连接和操作数据库,如MySQL、SQLite等。 6. Web开发:学习使用Python的Web框架(如Django、Flask)来构建网站和Web应用程序。 7. 数据分析和可视化:了解如何使用Python进行数据分析和可视化,如Pandas、Matplotlib等库的使用。 8. 机器学习和人工智能:介绍如何使用Python进行机器学习和人工智能的开发,如Scikit-learn、TensorFlow等。 通过完成这本书中的项目和挑战,读者可以逐步提高他们的Python编程能力,并且了解Python在不同领域的应用。这本书适合已经具备一定Python基础的读者,希望通过实践来进一步提升自己的编程技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值