uva 11374 Airport Express 机场快线 迪杰斯特拉算法

来源:互联网 发布:魔法王座升阶数据图片 编辑:程序博客网 时间:2024/04/26 01:05

题目链接:

https://uva.onlinejudge.org/external/113/11374.pdf

出发点为S,终点为E

令商业路线的起点为u和终点为v,那么总路线时间= d[S][u]+d[u][v]+d[v][E]

对起点S和终点E分别用dijkstra求出 d[S][u]和d[v][E],然后枚举商业路线,使其值最小,有可能不用商业路线。

细节见注释


int n,S,E;int d[2][maxn],pre[2][maxn];bool done[2][maxn];struct Eco  //存储商业路线{    int u,v;    int t;}  eco[2*maxk];struct Node   //dijkstra的优先队列元素{    int x,dis;    Node(){}    Node(int x,int dis):x(x),dis(dis){}    bool operator<(const Node b)const    {        return dis>b.dis;    }};struct Edge{    int u,v,t;    Edge(){}    Edge(int u,int v,int t):u(u),v(v),t(t){}};vector <int> G[maxn];vector<Edge> edges;void init(){    edges.clear();    for(int i=0;i<=n;i++)        G[i].clear();}void add_edge(int x,int y,int t){    edges.push_back( Edge(x,y,t));    edges.push_back( Edge(y,x,t));    int m=edges.size();    G[x].push_back(m-2);    G[y].push_back(m-1);}void dijkstra(int S,int d[maxn],int pre[maxn],bool done[maxn]){  //  memset(d,0x3f,sizeof d);   //这里似乎不能用memset,因为原本d[2][maxn],                                  // 这里只传了d[2]进来,可能是因为这个原因。    for(int i=1;i<=n;i++)        d[i]=INF;    d[S]=0;    priority_queue<Node> q;    q.push(Node(S,0) ); //   memset(done,0,sizeof done);  //用不了memsetfor(int i=1;i<=n;i++)    done[i]=0;    while(!q.empty())    {        Node tmp=q.top();q.pop();        int x=tmp.x;        if(done[x])  continue;        done[x]=true;        for(int i=0;i<G[x].size();i++)        {            int id=G[x][i];            Edge & e=edges[id];            int y=e.v;            if(done[y])  continue;            if(d[y]>d[x]+e.t)            {                d[y]=d[x]+e.t;                pre[y]=x;                q.push(Node(y,d[y]));            }        }    }}void print1(int x){    if(x==S)  {printf("%d",S);return;}    print1(pre[0][x]);    printf(" %d",x);}void print2(int x){      if(x==E)    {        printf(" %d\n",E);        return;    }    printf(" %d",x);    print2(pre[1][x]);}int main(){    int m,x,y,z,k,kase=0;//    cout<<INF<<endl;    while(~scanf("%d%d%d",&n,&S,&E))    {        init();        scanf("%d",&m);        for(int i=1;i<=m;i++)        {            scanf("%d%d%d",&x,&y,&z);            add_edge(x,y,z);        }        dijkstra(S, d[0], pre[0], done[0]);        dijkstra(E, d[1], pre[1], done[1]);        scanf("%d",&k);        int cnt=0;int ans=INF,p;        for(int i=1;i<=k;i++)        {            scanf("%d%d%d",&x,&y,&z);            eco[++cnt].u=x,eco[cnt].v=y,eco[cnt].t=z;            int ret=d[0][x]+d[1][y]+z;            if(ret <ans)  {ans=ret;p=cnt;}             eco[++cnt].u=y,eco[cnt].v=x,eco[cnt].t=z;   //商业路线也要考虑双向,前几次就是wa在这。               ret=d[0][y]+d[1][x]+z;               //结果改了过来,边数成了两倍又RE了,(数组开小了)              if(ret <ans)  {ans=ret;p=cnt;}        }        if(kase) puts("");        kase++;        if(d[0][E]>ans)        {             print1(  eco[p].u);             print2(  eco[p].v);             printf("%d\n",eco[p].u);             printf("%d\n",ans);        }       else       {           print1(E);putchar('\n');           puts("Ticket Not Used");            printf("%d\n",d[0][E]);       }    }    return 0;}




头文件:

#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<climits>#include<queue>#include<vector>#include<map>#include<sstream>#include<set>#include<stack>#include<utility>#pragma comment(linker, "/STACK:102400000,102400000")#define PI 3.1415926535897932384626#define eps 1e-10#define sqr(x) ((x)*(x))#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)#define  lson   num<<1,le,mid#define rson    num<<1|1,mid+1,ri#define MID   int mid=(le+ri)>>1#define zero(x)((x>0? x:-x)<1e-15)#define mk    make_pair#define _f     first#define _s     secondusing namespace std;const int INF =0x3f3f3f3f;const int maxn=   500+10  ;const int maxk=   1000+10  ;//const int INF=    ;typedef long long ll;const ll inf =1000000000000000;//1e15;//ifstream fin("input.txt");//ofstream fout("output.txt");//fin.close();//fout.close();//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);//by yskysker123


0 0