当前位置:文档之家› 杭电acm自己总结

杭电acm自己总结

1005 Number Sequence
Problem Description
A number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
Input
The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
Output
For each test case, print the value of f(n) on a single line.
Sample Input
1 1 3
1 2 10
0 0 0
Sample Output
2
5
百度解答:
这题结果是50个结果内必有循环,所以只需要求出前50个数据就可以了,后面的根据这50个结果推出来。计算出前50个结果,题目就简单了。
#include
using namespace std;
int main()
{
int a,b,n,i,s[1000];
while(scanf("%d%d%d",&a,&b,&n)==3)
{
if(!(a||b||n))
break;
s[0]=1;
s[1]=1;
for(i=2;i<50;i++)
{
s[i]=(s[i-1]*a+s[i-2]*b)%7;
if(i>4&&s[i]==s[2]&&s[i-1]==s[1]&&s[i-2]==s[0])
break;
}
n%=i-2;
if(n==0)
n=i-3;
else
n--;
cout<}
return 0;
}
百度解释:
1、这是大概是数论的问题,循环周期应该是7^变量个数,变量是两个,那么循环周期就是7^2=49。
2、因为num[i]是%7后得出的结果,而%7后有7种结果0,1,2,3,4,5,6;
那每次都是这7种结果中的一个,那最多7*7组结果就一定会出现循环;
例如第一组(每组7个数)第一个数0,第二组第一个数是1,一次类推,第七组第一个数是6;那么无论下一组第一个数出现的是什么都一定能这7组中找到一组与之相同;
建议你去看下抽屉原理。
3、f[n] = ( a * f[n - 1] + b * f[n - 2] ) % 7由于mod7所以f[n]所得的值最多有7种情况0 1 2 ... 6 那么a * x + b * y 的xy值也就只有7种情况组合起来就有7 * 7种所以在任何情况下,当执行了51次时按照鸽巢原理一定会出现重复的现象,由此可以找出周期。


1006
Problem Description
The three hands of the clock are rotating every second and meeting each other many times everyday. Finally, they get bored of this and each of them would like to stay away from the other two. A hand is happy if it is at least D degrees from any of the rest. You are to calculate how much time in a day that all the hands are happy.
Input
The input contains many test cases. Each of them has a single line with a real number D between 0 and 120, inclusively. The input is terminated with a D of -1.
Output
For each D, print in a single line the percentage of time in a day that all of the hands are happy, accurate up to 3 decimal places.
Sample Input
0
120
90
-1
Sample Output
100.000
0.000
6.251

错误代码:
#include
#include <

cstring>
#include
#include
using namespace std;
#define EPS 1e-9

int main(){
int n;
while (scanf("%d",&n) != EOF){
if(n == -1)break;

double ans = 0.0,tmp = n*1.0;
for(int i = 0; i < 60*43200; ++i){ //1秒拆成了60份
double a,b,c;
a = (double)(i%2592000)/7200.0;
b = (double)(i%216000)/600.0;
c = (double)(i%3600)/10.0;

double tmp1,tmp2,tmp3;
tmp1 = fabs(a - b);
tmp2 = fabs(a - c);
tmp3 = fabs(b - c);

tmp1 = min(360.0-tmp1,tmp1);
tmp2 = min(360.0-tmp2,tmp2);
tmp3 = min(360.0-tmp3,tmp3);

if(tmp1 + EPS < tmp || tmp2 + EPS < tmp || tmp3 + EPS < tmp)continue;
ans += 1.0;
}
printf("%.3lf\n",ans/(60.0*432.0));
}
return 0;
}

正确代码:
[code=C/C++]
// Problem 1006 Tick and Tick// Algorithm:
// ---- 稍加分析,可以发现对时间离散化计数行不通,因为要想达到精度,则必定超时.
// ---- 既然离散地统计不行,那就改为统计时间段. 试想,指针之间的夹角是关于时、分、秒的线性函数,
// ---- 如果时、分确定,那么我们就得到关于秒的线性不等式组,其解集必定是一些区间的交或并.
// ---- 容易从区间的交或并中统计出“快乐时光”的长度. 具体如下:
// ---- 设当前的时间为 H:M:S, 其中 0 <= H < 12, 0 <= M < 60, 0 <= S < 60, H,M皆为整数, S为实数
// ---- 于是时针、分针、秒针相对于时刻 0:0:0 的转角分别为
// ---- A(H) = 30H + M/2 + S/120;
// ---- A(M) = 6M + S/10;
// ---- A(S) = 6S;
// ---- 设题目中的临界夹角为 D,则“快乐时光”是同时满足以下不等式的解:
// ---- D <= | A(H) - A(M) | <= 360-D; (1)
// ---- D <= | A(H) - A(S) | <= 360-D; (2)
// ---- D <= | A(M) - A(S) | <= 360-D; (3)
// ---- 上面各式的绝对值中的形式为 bS - a,(a,b为常数,b>0) 故解的形式为
// ---- [ (a+D)/b, (a+360-D)/b) ] 并 [ (a+D-360)/b, (a-D)/b ], 即两个闭区间的并集.
// ---- 设由式(i)得到的解集为 Si1 并 Si2, 那么“快乐时光”在时、分确定的情况下,其秒的解集为
// ---- [0,60] 交 (S11 并 S12) 交 (S21 并 S22) 交 (S31 并 S32)
// ---- 上面的集合容易化成 S1 并 S2 并 S3 并 S4 并 S5 并 S6 并 S7 并 S8 的形式,其中 S1,S2,...皆为闭区间.
// ---- 求区间的并的总长度没有困难,而这个总长度就是由时、分确定的“快乐时光”的长度.
// Author: obtuseSword
// Date: 2008-08-29
// Compiler: Visual Studio 2005

#include
#include
using namespace std;
#define max(a,b) a>b?a:b;
#de

fine min(a,b) a// 区间结构
struct Segment{ double a,b; };

// 由两个区间求出它们的交(区间)
Segment operator *(Segment S1,Segment S2){
Segment seg;
seg.a = max(S1.a,S2.a);
seg.b = min(S1.b,S2.b);
if( seg.a >= seg.b )
seg.a = seg.b = 0.0;
return seg;
}

// “快乐时光”临界角度
double D;

// 从 D <= bS - a <= D1 中解出区间
Segment makeSeg1(double,double);
// 从 D <= a - bS <= D1 中解出区间
Segment makeSeg2(double,double);

//--------------------------- 主函数 ---------------------------//
int main(){
while( cin >> D, D != -1 ){
double totLen = 0.0; // “快乐时光”总长度
// 枚举时、分
for(int H = 0; H < 12; H++){
for(int M = 0; M < 60; M++){
Segment S[3][2];
// 获得基本解区间
double a, b;
a = 30.0 * H - 5.5 * M, b = 11.0/120;
S[0][0] = makeSeg1(a,b), S[0][1] = makeSeg2(a,b);
a = 30.0 * H + 0.5 * M, b = 719.0/120;
S[1][0] = makeSeg1(a,b), S[1][1] = makeSeg2(a,b);
a = 6.0 * M, b = 5.9;
S[2][0] = makeSeg1(a,b), S[2][1] = makeSeg2(a,b);
// 将解集转化为区间的并,并累计“快乐时光”的长度
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 2; k++){
Segment TS = S[0][i] * S[1][j] * S[2][k];
totLen += TS.b - TS.a;
}
}
}
// 输出“快乐时光”的比例
cout<<< totLen / 432.0 <}

return 0;
}
//---------------------------------------------------------------//

// 从 D <= bS - a <= D1 中解出区间
Segment makeSeg1(double a,double b){
Segment seg;
seg.a = (D+a)/b, seg.b = (360.0-D+a)/b;
if( seg.a < 0.0 )
seg.a = 0.0;
if( seg.b > 60.0 )
seg.b = 60.0;
if( seg.a >= seg.b )
seg.a = seg.b = 0.0;
return seg;
}

// 从 D <= a - bS <= D1 中解出区间
Segment makeSeg2(double a,double b){
Segment seg;
seg.a = (a+D-360.0)/b, seg.b = (a-D)/b;
if( seg.a < 0.0 )
seg.a = 0.0;
if( seg.b > 60.0 )
seg.b = 60.0;
if( seg.a >= seg.b )
seg.a = seg.b = 0.0;
return seg;
}

1007 Quoit Design
Problem Description
Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring.

Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.
Input
The input consists of several test cases. For each case, the first line contains a

n integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0.
Output
For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places.
Sample Input
2
0 0
1 1
2
1 1
1 1
3
-1.5 0
0 0
0 1.5
0
Sample Output
0.71
0.00
0.75

正确解答:
https://www.doczj.com/doc/4d2789164.html,.sg/~xujia/mirror/https://www.doczj.com/doc/4d2789164.html,/problems/problem_set/ndp/solution.htm
代码:(转载)

#include
#include
#include
using namespace std;

struct node
{
double x,y;
}point[100000];
int n;

bool cal_less(node p1,node p2)
{
if(p1.x != p2.x) return p1.x < p2.x;
else return p1.y < p2.y;
}

double dist(node a, node b)
{
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}

double getmin(double a, double b)
{
return a}

double solve(int l,int r)
{
if(l == r)
return 1000000000;
if(l == r - 1)
return dist(point[l],point[r]);
if(l == r - 2)
return getmin(getmin(dist(point[l],point[l+1]),dist(point[l+1],point[l+2])),dist(point[l],point[l+2]));
int i,j,mid = (l+r) >> 1;
double curmin = getmin(solve(l,mid),solve(mid+1,r));
for(i=l;i<=r;i++)
for(j=i+1;j<=i+5 && j<=r;j++)
{
curmin = getmin(curmin,dist(point[i],point[j]));
}
return curmin;
}

int main()
{
int i;
while(scanf("%d",&n)!=EOF && n)
{
for(i=0;iscanf("%lf %lf",&point[i].x,&point[i].y);
sort(point,point+n,cal_less);
double ans = solve(0,n-1);
printf("%.2lf/n",ans/2);
}
return 0;
}

原创代码:
#include
#include
#include
using namespace std;

struct point{
double x;
double y;
}p[1000000];

bool cal_less(point p1,point p2)
{
if(p1.x != p2.x)
return p1.x < p2.x;
else
return p1.y < p2.y;
}

double dis(point p1,point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double getmin(double a,double b)
{
return a
}
double getmin(point p1,point p2, point p3)
{
double a=dis(p1,p2);
double b=dis(p3,p2);
double c=dis(p1,p3);
if(a{
if(areturn a;
else
return c;
}
else
{
if(b>c)
return c;
else
return b;
}
}
double search(int l,int r)
{
if(l==r)
return 100000000;
if(l+1==r)
return dis(p[l],p[r]);
if(l+2==r)
return getmin(p[l],p[l+1],p[r]);
int mid=(l+r)/2;
double curmin=getmin(search(l,mid),search(mid+1,r));

for(int i=l;i<=mid+1;i++)
if(p[i].x-p[mid].x<=curmin)
for(int j=i+1;jif(dis(p[i],p[j])curmin=dis(p[i],p[j]);
return curmin;
}

int main()
{
int n;
scanf("%d",&n);
while(n>0)
{
for(int i=0;iscanf("%lf%lf",&p[i].x,&p[i].y);
sort(p,p+n,cal_less);
printf("%.2lf/n",search(0,n-1)/2);
scanf("%d",&n);
}
return 0;
}

其他代

码:
#include
#include
#include
using namespace std;

const int N=200002;
const double EPS=1e-10;
const double INF=1e20;

struct Point
{
double x,y;
}
p[N];
int n,o[N],on;

inline double dis(const Point & a,const Point & b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

inline int dcmp(double a,double b)
{
if(a-breturn 0;
if(a>b)
return 1;
return -1;
}

inline bool cmp_x(const Point & a,const Point & b)
{
return dcmp(a.x,b.x)<0;
}

inline bool cmp_y(const int & a,const int & b)
{
return dcmp(p[a].y,p[b].y)<0;
}

inline double min(double a,double b)
{
return a}

double search(int s,int t)
{
int mid=(s+t)>>1,i,j;

double ret=INF;

if(s>=t)
return ret;

for(i=mid;i>=s && ! dcmp(p[i].x,p[mid].x);--i);
ret=search(s,i);

for(i=mid;i<=t && ! dcmp(p[i].x,p[mid].x);++i);
ret=min(ret,search(i,t));

on=0;
for(i=mid;i>=s && dcmp(p[mid].x-p[i].x,ret)<=0;--i)
o[++on]=i;

for(i=mid+1;i<=t && dcmp(p[i].x-p[mid].x,ret)<=0;++i)
o[++on]=i;

sort(o+1,o+on+1,cmp_y);

for(i=1;i<=on;++i)
{
for(j=1;j<=10;++j)
{
if(i+j<=on)
ret=min(ret,dis(p[o[i]],p[o[i+j]]));
}
}
return ret;
}

int main()
{
while(scanf("%d",&n)-EOF && n!=0)
{
for(int i=1;i<=n;++i)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+n+1,cmp_x);
double sum=search(1,n);
printf("%.2lf\n",sum/2);
}
return 0;
}
题目大意:给出平面上的n(2 <= n <= 100,000)个点,要求求出最近点对。因为题目要的圆的半径,所以,最后除以2就ok了。

很多书上都说到一种用分治的方法,而且在合并的时候,枚举的点数会在6个点以内(据说有人证明只要三个点),但是我用吉大的模板敲了好久之后,居然老是wa,很诡异的wa,貌似在最后的那组数据卡到了(1171ms wa),没办法,自己用了一个很贱的方法试了一下 ,居然AC了。

其实我的方法是一定范围内的枚举,对点进行x轴排序,这样,可以知道最短的距离最有可能出现的是在两个相邻的点之间(但不一定),所以我枚举了离当前点距离(只看x轴)最近的50个点,这样,最短距离一般就在里面了。

对于y轴也用同样的方法去枚举。

我的代码:

#include
#include
#include
#define min(x,y) xstruct P
{
double x, y;
}p[100003];
int n;
double ans;
int cmp1(const void *a,const void *b)
{
struct P *c=(P *)a;
struct P *d=(P *)b;
if (c->x==d->x)
return ((P *)c)->y>((P *)d)->y?-1:1;
return ((P *)c)->x>((P *)d)->x?-1:1;
}
int cmp2(const void *a,const void *b)
{
struct P *c=(P *)a;
struct P *d=(P *)b;
if (c->y==d->y)
return ((P *)c)->x>((P *)d)->x?-1:1;
return ((P *)c)->y>((P *)d)->y

?-1:1;
}
void work()
{
int i,j;
for (i=0;ifor (j=i+1;jans=min((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y),ans);
}
int main()
{
int i;
while (scanf("%d",&n)!=EOF&&n)
{
for (i=0;iscanf("%lf %lf",&p[i].x,&p[i].y);
ans = 2100000000;
qsort(p,n,sizeof(p[0]),cmp1);
work();
qsort(p,n,sizeof(p[0]),cmp2);
work();
printf("%.2lf\n",sqrt(ans)/2);
}
return 0;
}

PS:枚举两个轴,且都枚举50个点 AC了

慢慢的减少枚举数,居然只枚举一个轴,而且只要5个点即就OK了

这数据也太弱了吧


吉大模板的代码:

#include
#include
#include
#include
#include
using namespace std;
const int N = 100005;
const double MAX = 10e100;
const double eps = 0.00001;
typedef struct TYPE
{
double x, y;
int index;
} Point;
Point a[N], b[N], c[N];
double closest(Point *, Point *, Point *, int, int);
double dis(Point, Point);
int cmp_x(const void *, const void*);
int cmp_y(const void *, const void*);
int merge(Point *, Point *, int, int, int);
inline double min(double, double);

int main()
{
int n, i;
double d;
scanf("%d", &n);
while (n)
{
for (i = 0; i < n; i++)
scanf("%lf%lf", &(a[i].x), &(a[i].y));
qsort(a, n, sizeof(a[0]), cmp_x);
for (i = 0; i < n; i++)
a[i].index = i;
memcpy(b, a, n *sizeof(a[0]));
qsort(b, n, sizeof(b[0]), cmp_y);
d = closest(a, b, c, 0, n - 1);
printf("%.2lf\n", d/2);
scanf("%d", &n);
}
return 0;
}

double closest(Point a[], Point b[], Point c[], int p, int q)
{
if (q - p == 1)
return dis(a[p], a[q]);
if (q - p == 2)
{
double x1 = dis(a[p], a[q]);
double x2 = dis(a[p + 1], a[q]);
double x3 = dis(a[p], a[p + 1]);
if (x1 < x2 && x1 < x3)
return x1;
else if (x2 < x3)
return x2;
else
return x3;
}
int m = (p + q) / 2;
int i, j, k;
double d1, d2;
for (i = p, j = p, k = m + 1; i <= q; i++)
if (b[i].index <= m)
c[j++] = b[i];
//数组c左半部保存划分后左部的点, 且对y是有序的.
else
c[k++] = b[i];
d1 = closest(a, c, b, p, m);
d2 = closest(a, c, b, m + 1, q);
double dm = min(d1, d2);
merge(b, c, p, m, q); //数组c左右部分分别是对y坐标有序的, 将其合并到b.
for (i = p, k = p; i <= q; i++)
if (fabs(b[i].x - b[m].x) < dm)
c[k++] = b[i];
//找出离划分基准左右不超过dm的部分, 且仍然对y坐标有序.
for (i = p; i < k; i++)
for (j = i + 1; j < k && c[j].y - c[i].y < dm; j++)
{
double temp = dis(c[i], c[j]);
if (temp < dm)
dm = temp;
}
return dm;
}


double dis(Point p, Point q)
{
double x1 = p.x - q.x, y1 = p.y - q.y;
return sqrt(x1 *x1 + y1 * y1);
}

int merge(Point p[], Point q[], int s, int m, int t)
{
int i, j, k;
for (i = s, j = m + 1, k = s; i <= m && j <= t;)
{
if (q[i].y > q[j].y)
p[k++] = q[j], j++;
else
p[k++] = q[i], i++;
}
while (i <= m)
p[k++] = q[i++];
while (j <= t)
p[k++] = q[j++];
memcpy(q + s, p + s, (t - s + 1) *sizeof(p[0]));
return 0;
}

int cmp_x(const void *p, const void *q)
{
double temp = ((Point*)p)->x - ((Point*)q)->x;
if (temp > 0)
return 1;
else if (fabs(temp) < eps)
return 0;
else
return - 1;
}

int cmp_y(const void *p, const void *q)
{
double temp = ((Point*)p)->y - ((Point*)q)->y;
if (temp > 0)
return 1;
else if (fabs(temp) < eps)
return 0;
else
return - 1;
}

inline double min(double p, double q)
{
return (p > q) ? (q): (p);
}
1008 Elevator
Problem Description
The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor, and 4 seconds to move down one floor. The elevator will stay for 5 seconds at each stop.

For a given request list, you are to compute the total time spent to fulfill the requests on the list. The elevator is on the 0th floor at the beginning and does not have to return to the ground floor when the requests are fulfilled.

Input
There are multiple test cases. Each case contains a positive integer N, followed by N positive numbers. All the numbers in the input are less than 100. A test case with N = 0 denotes the end of input. This test case is not to be processed.

Output
Print the total time on a single line for each test case.
Sample Input
1 2
3 2 3 1
0
Sample Output
17
41

1009 FatMouse' Trade

Problem Description
FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.



Input
The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1's. All integers are not greater than 1000.



Output
For each test case, print in a single line a real number accurate

up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.



Sample Input
5 3
7 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1


Sample Output
13.333
31.500

1010 Tempter of the Bone

Problem Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.



Input
The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.

The input is terminated with three 0's. This test case is not to be processed.



Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.



Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0


Sample Output
NO
YES

1011 Starship Troopers

Problem Description
You, the leader of Starship Troopers, are sent to destroy a base of the bugs. The base is built underground. It is actually a huge cavern, which consists of many rooms connected with tunnels. Each room is occupied by some bugs, and their brains hide in some of the rooms. Scientists have just developed a new weapon and want to experiment it on some brains. Your task is to destroy the whole base, and capture as many brains as possible.

To kill all the bugs is always easier than to capture their brains. A map is drawn for you, with all the rooms marked by the amount of bugs inside, and the possibility of containing a brain. The cavern's structure is like a tree in such a way that there is one unique path leading to each room from the entrance. To finish the battle as soon as possible, you do not want to wait for the troopers to clear a room before advancing to the next one, instead you have to leave some troopers at each room passed to fight all the bugs inside. The troopers never re-enter

a room where they have visited before.

A starship trooper can fight against 20 bugs. Since you do not have enough troopers, you can only take some of the rooms and let the nerve gas do the rest of the job. At the mean time, you should maximize the possibility of capturing a brain. To simplify the problem, just maximize the sum of all the possibilities of containing brains for the taken rooms. Making such a plan is a difficult job. You need the help of a computer.



Input
The input contains several test cases. The first line of each test case contains two integers N (0 < N <= 100) and M (0 <= M <= 100), which are the number of rooms in the cavern and the number of starship troopers you have, respectively. The following N lines give the description of the rooms. Each line contains two non-negative integers -- the amount of bugs inside and the possibility of containing a brain, respectively. The next N - 1 lines give the description of tunnels. Each tunnel is described by two integers, which are the indices of the two rooms it connects. Rooms are numbered from 1 and room 1 is the entrance to the cavern.

The last test case is followed by two -1's.



Output
For each test case, print on a single line the maximum sum of all the possibilities of containing brains for the taken rooms.



Sample Input
5 10
50 10
40 10
40 20
65 30
70 30
1 2
1 3
2 4
2 5
1 1
20 7
-1 -1


Sample Output
50
7

1012

相关主题
文本预览