分糖果(图论算法)

Description

童年的我们,将和朋友分享美好的事物作为自己的快乐。这天,C小朋友得到了Plenty of candies,将要把这些糖果分给要好的朋友们。已知糖果从一个人传给另一个人需要1 秒的时间,同一个小朋友不会重复接受糖果。由于糖果足够多,如果某时刻某小朋友接受了糖果,他会将糖果分成若干份,分给那些在他身旁且还没有得到糖果的小朋友们,而且自己会吃一些糖果。由于嘴馋,小朋友们等不及将糖果发完,会在得到糖果后边吃边发。每个小朋友从接受糖果到吃完糖果需要m秒的时间。那么,如果第一秒C小朋友开始发糖,第多少秒所有小朋友都吃完了糖呢? 输入格式 Input Format 第一行为三个数n、p、c,为小朋友数、关系数和C小朋友的编号。 
第二行为一个数m,表示小朋友吃糖的时间。 

Input

第一行为三个数n、p、c,为小朋友数、关系数和C小朋友的编号。 
第二行为一个数m,表示小朋友吃糖的时间。 
下面p行每行两个整数,表示某两个小朋友在彼此身旁 

Output

一个数,为所有小朋友都吃完了糖的时间 

Sample Input

 

4 3 1 

1 2 
2 3 
1 4

 

Sample Output

 

5

 

Hint

40%的数据满足:1<=n<=100 
60%的数据满足:1<=n<=1000 
100%的数据满足:1<=n<=100000 
m<=n*(n-1)/2,不会有同一个关系被描述多次的情况。



解题思路:先读入数据,用邻接矩阵储存,然后用spfa算法求最短路,也就是求出到最后一个小朋友的时间,最后用这个时间加上最后一个小朋友吃糖的时间输出即可。



程序:

const

  maxn=100000;

  maxv=2500000;

type

  rec=record

        x,y,next:longint;

      end;

var

  g:array[1..maxv] of rec;

  ls,list,dis:array[1..maxn] of longint;

  v:array[1..maxn] of boolean;

  n,e,s,m,p,c,ans:longint;


procedure add(x,y:longint);

  begin

    inc(e);

    g[e].x:=x;

    g[e].y:=y;

    g[e].next:=ls[x];

    ls[x]:=e;

end;


procedure init;

  var

    i,x,y:longint;

  begin

    e:=0;

    fillchar(ls,sizeof(ls),0);

    fillchar(dis,sizeof(dis),$7f);

    readln(n,p,c);

    dis[c]:=1;

    ans:=1;

    readln(m);

    for i:=1 to p do

      begin

        readln(x,y);

        add(x,y);

        add(y,x);

      end;

end;


procedure spfa(s:longint);

  var

    head,tail,t:longint;

  begin

    head:=0;

    tail:=1;

    v[s]:=true;

    list[1]:=s;

    repeat

      inc(head);

      t:=ls[list[head]];

      while t>0 do

        with g[t] do

          begin

            if dis[x]+1

              begin

                dis[y]:=dis[x]+1;

                if ans

                if not v[y] then

                  begin

                    v[y]:=true;

                    inc(tail);

                    list[tail]:=y;

                  end;

              end;

            t:=next;

          end;

      v[list[head]]:=false;

    until head=tail;

end;


begin

  init;

  spfa(c);

  ans:=ans+m;

  writeln(ans);

end.


版权属于: Chris

原文地址: http://blog.sina.com.cn/s/blog_83ac6af80102v22v.html

转载时必须以链接形式注明原始出处及本声明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值