poj 2457 Part Acq…

该博客主要介绍了一个关于商品交换的问题,即从商品1出发,通过多次交换达到商品k的最短路径。作者使用了最短路算法(Dijkstra算法)来解决这个问题,并给出了相应的代码实现。在代码中,建立了边表并实现了Dijkstra算法,最后输出了最短路径和交换顺序。
摘要由CSDN通过智能技术生成
题意:cows 想用自己手上的商品(1)通过多次交换得到想要的商品(k),给出两种商品的交换关系,求出至少有多少种商品经过交换,输出交换的顺序。

思路:最短路。相当于求从1商品到k商品的最短路径,中间再记录一下结点信息。我用的是边表实现dij算法


//412K      79MS
#include
#include

const int EM = 50010;
const int VM = 1005;
const int inf = 0x3f3f3f3f;

struct Edge
{
      int frm,to,nxt;
}edge[EM];

int head[VM],vis[VM],dis[VM],pre[VM];
int e,n,sta,end,ans;
bool mark;

void addedge(int cu,int cv)
{
      edge[e].frm = cu;
      edge[e].to = cv;
      edge[e].nxt = head[cu];
      head[cu] = e ++;
}
void print(int tmp)//输入路径
{
      ++ans;
      if (tmp != -1)
              print(pre[tmp]);
      if (tmp == -1)
              return ;
      if (!mark)
      {
              printf ("%d\n",ans);
              mark = true;
      }
      printf ("%d\n",tmp);
}
void Dij()
{
      int i;
      memset (vis,0,sizeof(vis));
      memset (dis,0x3f,sizeof(dis));
      memset (pre,-1,sizeof(pre));
      for (i = head[sta];i != -1;i = edge[i].nxt)
      {
              dis[edge[i].to] = 1;
              pre[edge[i].to] = sta;
      }
      pre[sta] = -1,vis[sta] = 1;
      int cnt = n - 1;
      while (cnt --)
      {
              int min = inf;
              int flag;
              for (i = 1;i <= end;i ++)
                      if (!vis[i]&&dis[i] < min)
                              flag = i,min = dis[i];
              vis[flag] = 1;
              for (i = head[flag];i != -1;i = edge[i].nxt)
              {
                      int v = edge[i].to;
                      if (!vis[v]&&dis[v]>dis[flag]+1)
                      {
                              dis[v] = dis[flag] + 1;
                              pre[v] = flag;              //v的前驱是flag
                      }
              }
      }
      if (dis[end] == inf) //无路径
              printf ("-1\n");
      else
      {
              mark = false;
              ans = -1;
              int tmp = end;
              print(tmp);
      }
}
int main ()
{
      while (~scanf ("%d%d",&n,&end))
      {
              e = 0;
              sta = 1;
              memset (head,-1,sizeof(head));
              for (int i = 0;i < n;i ++)
              {
                      int u,v;
                      scanf ("%d%d",&u,&v);
                      addedge(u,v);
              }
              Dij();
      }
      return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值