Hoj 1948 回家

题目:http://acm.hit.edu.cn/hoj/problem/view?id=1948

这题怎么说呢,题目出的挺好的,Dijkstra。既有边权又有点权。加一维处理点权。

但是仍有不少疑问,我提交了有20次了吧。都刷屏了。快。各种试。。有两个地方至今仍不理解。

1.关于mapp对角线初始化为0 的问题,难道不需要初始化为0么?初始化为0反而A不掉。

2.起点和终点不可以交换顺序么?这不一样么?可是Harbin只能做终点是怎么回事。。

捶桌。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>

using namespace std;

int mapp[102][102][2];
int dist[102][2];
int visited[102][2];

int main()
{

#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    char de[22];
    char te1[22],te2[22];
    int t;
    char trans[8];
    map<string,int> m;
    int n;
    int startC;
    int endC;
    while(scanf(" %s",de)!=EOF)
    {
        m.clear();
        scanf(" %d",&n);
        memset(mapp,0x3f,sizeof(mapp));

        for(int i=0; i<n; i++)
        {
            scanf(" %s %s %s %d",trans,te1,te2,&t);
            if(m.find(te1) == m.end())
            {
                m.insert(make_pair(te1,m.size()));
            }
            if(m.find(te2) ==  m.end())
            {
                m.insert(make_pair(te2,m.size()));
            }
            if(trans[0] == 't')
            {
                mapp[m[te1]][m[te2]][1] = mapp[m[te2]][m[te1]][1] = t;//1维是火车
            }
            else
            {
                mapp[m[te1]][m[te2]][0] = mapp[m[te2]][m[te1]][0] = t;//0维是汽车
            }
        }
        //加上就不行,为何?
        /*for(int i=0; i<m.size(); i++)
        {
            mapp[i][i][0] = mapp[i][i][1] = 0;
        }*/
        //endC和startC不能颠倒?
        endC = m["Harbin"];
        startC = m[de];

        memset(dist,0x3f,sizeof(dist));
        memset(visited,0,sizeof(visited));
        n = m.size();
        for(int i=0; i<n; i++)
            for(int k=0; k<2; k++)
                dist[i][k]=mapp[startC][i][k];

        dist[startC][0] = 0;
        dist[startC][1] = 0;
        visited[startC][0] = 1;
        visited[startC][1] = 1;

        for(int i=0; i<n; i++)
        {
            int min = 0x3f3f3f3f;
            int k = 0;
            int k1 = 0;
            for(int j=0; j<n; j++)
            {
                for(int u=0; u<2; u++)
                {
                    if(visited[j][u] == 0 && dist[j][u]<min)
                    {
                        min = dist[j][u];
                        k = j;
                        k1 = u;
                    }
                }
            }
            visited[k][k1] = 1;
            for(int j=0; j<n; j++)
            {
                for(int u=0; u<2; u++)
                {
                    int plus;
                    if(u == k1)
                    {
                        plus = 3;
                    }
                    else
                    {
                        plus = 10;
                    }

                    if(dist[j][u] > dist[k][k1] + mapp[k][j][u] + plus)
                    {
                        dist[j][u] = dist[k][k1] + mapp[k][j][u] + plus;
                    }
                }
            }
        }

        printf("%d\n",min(dist[endC][0],dist[endC][1]));
    }
    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值