Flight

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3499

注:最短路变形

源代码:

#include <stdio.h>
#include <queue>
#include <string.h>
#include <map>
#include <iostream>
#define M 500005
#define N 100005
#define INF 1e17

using namespace  std;
typedef __int64 ll;

int n,m,id,ww;

ll ans,tmp;

ll d[N],d1[N];

int vis[N],head[2*M];

string s1,s2;

typedef  struct
{
 int nxt,u,v,w;
}edge;

edge e[2*M];

map<string,int>Map;

typedef struct
{
    int num;
    ll dist;

}node;

bool operator <(const node s,const node t)
{
    return s.dist>t.dist;
}

void add(int u,int v,int w)
{
    e[id].w=w;  e[id].u=u;
    e[id].v=v;
    e[id].nxt=head[u];
    head[u]=id;
    id++;
}

void pri_dij(int s,ll d[],int flag)
{
  priority_queue<node>q;
  node b;
  for(int i=1;i<=n;i++)  { d[i]=INF;  vis[i]=0; }
  d[s]=0;
  b.num=s;  b.dist=0;
  q.push(b);
  while(!q.empty())
  {
      b=q.top();  q.pop();
      int u=b.num;
      if(vis[u])  continue;
      vis[u]=1;
      for(int i=head[u];i!=0;i=e[i].nxt)
      {
          int x=e[i].v,y;
          if(flag)  y=1;
          else  y=0;
          if(i%2==y&&vis[x]==0&&d[x]>d[u]+e[i].w)
           {
              d[x]=d[u]+e[i].w;
              b.dist=d[x], b.num=x;
              q.push(b);
           }
      }
  }
}

int main()
{
   freopen("D:\\a.txt","r",stdin);
    while(~scanf("%d %d",&n,&m))
    {
      int cnt=1;  Map.clear();  id=1;
      memset(e,0,sizeof(e));
      memset(head,0,sizeof(head));
     for(int i=0;i<m;i++)
      {
          cin>>s1>>s2>>ww;
          if(Map.find(s1)==Map.end())
          {
              Map[s1]=cnt++;
          }
          if(Map.find(s2)==Map.end())
          {
              Map[s2]=cnt++;
          }
          add(Map[s1],Map[s2],ww);
          add(Map[s2],Map[s1],ww);
      }
      cin>>s1>>s2;
      if(Map.find(s1)==Map.end()||Map.find(s2)==Map.end())
      {
          printf("-1\n");  continue;
      }
      if(Map[s1]==Map[s2])
      {
          printf("0\n");  continue;
      }
      pri_dij(Map[s1],d,1);
      pri_dij(Map[s2],d1,0);
      ans=INF;
      for(int i=1;i<=2*m;i+=2)
      {
          tmp=e[i].w/2+d1[e[i].v]+d[e[i].u];
          if(ans>tmp)
           ans=tmp;
      }
      if(ans==INF)
      printf("-1\n");
      else
      printf("%I64d\n",ans);
    }
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值