【NOIP2013模拟】开心小屋

【NOIP2013模拟】开心小屋 (Standard IO)

Memory Limits: 262144 KB
Description
Kc来到开心小屋。开心小屋是用来提升心情的。在这个小屋中有n个房间,一些房间之间有门连通。从房间i到达房间j,心情值可以加上-10000<=Cij<=10000,当然Cij可能是负的。现在kc失恋了,所以他想要知道他是否可以在这个小屋中无限地增加他的心情值,也就是无限地绕着一个环走?

请帮kc求出最小的环需要经过的房间数,来使他的心情无限增加。

Input
第一行给出,1<=n<=300,1<=m<=5000。分别表示房间数及门的数量。

接下来m行,每行四个数:i,j,Cij,Cji

Output
输出文件包括一行,及最小的环需要经过的房间数。

保证不会出现自环及重边。

Sample Input
4 4
1 2 -10 3
1 3 1 -10
2 4 -10 -1
3 4 0 -3

Sample Output
4

样例解释:
1—>3—>4–>2–>1为最小的符合题意的环长度为4.

Data Constraint
对30%的数据,n<=10;
对60%的数据,,n<=100;
对100%的数据,n<=300;


此题有个比较难理解的地方:最小的环需要经过的房间数,有一些指代不明(最小的环,它所经过的个数;所有环经房间个数的最小值)。
经过反复试验,发现它指的是后者。


现在,讲讲解题的方法:
——明显就是暴搜
枚举每一个起始点,递归寻环,将环的长度更新答案,环的长度用前缀和计算。
——但是这样肯定会超时,所以我们需要几个小小的剪枝,然而就是这些剪枝起了大大的作用。

  1. 倘若当次递归所搜过的屋子个数超过了先前找的答案,exit掉。
  2. 倘若从起点到当前位置,它的值已经成了负数,exit掉。

codes

var a,r:array[1..300,0..300]of longint;
    bz:array[1..300]of boolean;
    f,num:array[1..300]of longint;
    n,m,x,y,z1,z2,i,sum:longint;
procedure doit(n,v,t:longint);
    var o,x,y:longint;
begin
    if v<0 then exit;
    if t>=sum then exit;
    if bz[n] then
    begin
        if v-f[n]<=0 then exit;
        if t-num[n]<sum then sum:=t-num[n];
        exit;
    end;
    bz[n]:=true;
    f[n]:=v; num[n]:=t;
    for o:=1 to a[n,0] do
    begin
        x:=a[n,o]; y:=r[n,o];
        doit(x,v+y,t+1);
    end;
    bz[n]:=false;
end;
begin
    read(n,m);
    for i:=1 to m do
    begin
        read(x,y,z1,z2);
        inc(a[x,0]);
        a[x,a[x,0]]:=y; r[x,a[x,0]]:=z1;
        inc(a[y,0]);
        a[y,a[y,0]]:=x; r[y,a[y,0]]:=z2;
    end;
    sum:=maxlongint;
    for i:=1 to n do doit(i,0,0);
    writeln(sum);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值