• HDU 4522


    假设湫湫有可能经过的n个城市分别编号从1到n,湫湫要从城市A回到城市B,购票网站上列出了t辆列车行程,每辆车的行程用一个字符串表示,途径的城市间用+号相连,如1+2+3+5代表一辆从1城市分别经过2,3到达5的火车,湫湫可以从中间任意一站出发和下车(路径是单向的,即必须沿字符串从左到右来走),每个字符串对应着一个整数k,k=0表示该车只有硬座,k=1表示该车有卧铺也有硬座,在整个回家的计划中,同一辆车可以坐无限次,为了中途换车的方便,如果在起点坐的是卧铺,则后面乘坐的车必须全是卧铺,同样的,如果在起点坐的是硬座,则后面乘坐的车必须全是硬座,假设一段(一辆车行程中,两相邻城市间为一段)硬座的不舒适度是D1,一段卧铺的不舒适度是D2,求湫湫回家最小的不舒适度。

    因为题目要求只能一直都坐硬卧或一直都坐软卧,所以要2遍最短路。

    View Code
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    const int Max = 209;
    #define inf 1<<28
    #define min(a,b) a<b?a:b
    int mat[Max][Max];
    int map[Max][Max];
    char ss[Max*100];
    int dis[Max];
    bool vis[Max];
    int n,m;
    
    void dij1(int s) {
        memset(vis,0,sizeof(vis));
        for(int i = 1; i <=n ; i++)
            dis[i] = mat[s][i];
        vis[s] = 1;
        while(1) {
            int mmin = inf;
            int p = -1;
            for(int i = 1; i <= n; i++) {
                if(dis[i] < mmin && !vis[i]) {
                    p = i;
                    mmin = dis[i];
                }
            }
            if(p == -1)
                break;
            vis[p] = 1;
            for(int i = 1; i <= n; i++) {
                if(!vis[i] && dis[i] > dis[p] + mat[p][i])
                    dis[i] = dis[p] + mat[p][i];
            }
        }
    }
    
    void dij2(int s) {
        memset(vis,0,sizeof(vis));
        for(int i = 1; i <=n ; i++)
            dis[i] = map[s][i];
        vis[s] = 1;
        while(1) {
            int mmin = inf;
            int p = -1;
            for(int i = 1; i <= n; i++) {
                if(dis[i] < mmin && !vis[i]) {
                    p = i;
                    mmin = dis[i];
                }
            }
            if(p == -1)
                break;
            vis[p] = 1;
            for(int i = 1; i <= n; i++) {
                if(!vis[i] && dis[i] > dis[p] + map[p][i])
                    dis[i] = dis[p] + map[p][i];
            }
        }
    }
    
    int main() {
        int t;
        scanf("%d",&t);
        while(t--) {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++) {
                for(int j=1;j<=n;j++) {
                    mat[i][j] = inf;
                    map[i][j] = inf;
                }
            }
            for(int i=0;i<m;i++) {
                int x;
                scanf("%s",ss);
                scanf("%d",&x);
                int len = strlen(ss);
                int s1 = 0,s2 = 0;
                int j = 0;
                while(ss[j] != '+') {
                    s1 = s1*10 + ss[j]-'0';
                    j++;
                }
                for(j++; j < len ;j++) {
                    while(ss[j] != '+' && j < len) {
                        s2 = s2*10 + ss[j]-'0';
                        j++;
                    }
                    if(x == 1)
                        mat[s1][s2] = 1;
                    else
                        mat[s1][s2] = 0;
                    s1 = s2;
                    s2 = 0;
                }
            }
            int v1,v2;
            int s,e;
            scanf("%d%d",&v1,&v2);
            scanf("%d%d",&s,&e);
            for(int i = 1;i <= n;i++) {
                for(int j = 1; j <= n; j++) {
                    if(mat[i][j] == 1){
                        map[i][j] = v2;
                        mat[i][j] = v1;
                    }
                    else if(mat[i][j] == 0)
                        mat[i][j] = v1;
                }
            }
            dij1(s);
            int ans1 = dis[e];
            dij2(s);
            int ans2 = dis[e];
            int ans = min(ans1,ans2);
            if(ans >= inf)
                printf("-1\n");
            else
                printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    (CS模式)大学计算机基础考试系统
    四叶草的祝福
    做人的小故事!
    前天晚上回到北京了
    人生活的三种状态
    松口气了!
    Mysql一些基础用法
    云计算随想
    对vector与deque插值与遍历的性能数据
    gdb命令的常用调试选项
  • 原文地址:https://www.cnblogs.com/gray035/p/2982923.html
Copyright © 2020-2023  润新知