[最短路]xt 1141 Bus Transit

来源:互联网 发布:知网 社会经济数据库 编辑:程序博客网 时间:2024/04/28 11:36
/**[最短路]xt 1141 Bus Transit公交图上有一些线路,同一站点可能存在于不同线路上或在一线路上出现多次,公交线路的换乘需要一定的时间代价T求从起点到终点的最小时间(相同情况下选择最小换乘路线)题意很明显是最短路,跑一圈dijkstra即可,这要求图上每个点都不一样,如果把同名站点拆开,两两之间建立权为T的边肯定会TLE。仔细考虑,同名站点的换乘肯定是从最短到达进行换乘的,即dijkstra时若首次弹出某个站点,则一次更新所有同名的站点(带换乘方案的)。于是,每个站点有两个编号,一是输入中的顺序编号,二是所属于那个同名站点的集合,前者朴素dijkstra,后者转乘方案*/#include <stdio.h>#include <string.h>#include <string>#include <map>#include <vector>#include <iostream>#include <queue>#include <algorithm>using namespace std;#define N 100007#define INF 1000000000#define Pii pair<int,int>#define MK make_pairint id[N],vis[N],trans[N],d[N],dt[N];int cnt,k,n,t,w;string S,B,str;vector< Pii > g[N];vector<int > tpot[N];map<string,int > smp;void dij(){    int u,v,i,j;    int s = smp[S],b = smp[B];    memset(vis,0,sizeof(vis));    for(i = 0; i < cnt; ++i)        d[i] = INF;    priority_queue<Pii,vector<Pii>,greater<Pii> > que;    for(i = 0;  i < tpot[s].size(); ++i)    {        u = tpot[s][i];        d[u] = dt[u] = 0;        que.push(MK(0,u));    }    while(!que.empty())    {        u = que.top().second;        k = id[u];        if(k == b)        {            printf("%d %d\n",d[u],dt[u]);            return ;        }        que.pop();        if(vis[u])            continue;        vis[u] = 1;        for(i = 0; i < g[u].size(); ++i)        {            v = g[u][i].first;            w = g[u][i].second;            if(d[v] > d[u] + w)            {                d[v] = d[u] + w;                dt[v] = dt[u];                que.push(MK(d[v],v));            }        }        if(trans[k] == 0)        {            trans[k] = 1;            for(i = 0; i < tpot[k].size(); ++i)            {                v = tpot[k][i];                if(v == u)                    continue;                if(d[v] > d[u] + t)                {                    d[v] = d[u] + t;                    dt[v] = dt[u] + 1;                    que.push(MK(d[v],v));                }            }        }    }    puts("-1");}int main(){    int i,a;    while(scanf("%d%d",&n,&t) != EOF)    {        cin >> S >> B;        memset(trans,-1,sizeof(trans));        memset(g,0,sizeof(g));        memset(tpot,0,sizeof(tpot));        smp.clear();        cnt = 0;        while(n--)        {            k = cnt + 1;            scanf("%d",&a);            for(i = 0; i < a; ++i)            {                cin >> str;                if(smp.find(str) == smp.end())                    smp[str] = smp.size();                else                    trans[smp[str]] = 0;                id[cnt] = smp[str];                tpot[id[cnt]].push_back(cnt);                ++cnt;            }            for(i = 1; i < a; ++i,++k)            {                scanf("%d",&w);                g[k].push_back(MK(k-1,w));                g[k-1].push_back(MK(k,w));            }        }        dij();    }    return 0;}