您的位置:首页 > 其它

[机房考试] 图论 题解

2017-01-19 20:46 225 查看
Problem 1. Study

Input file: study.in

Output file: study.out

Time limit: 2 second

jyb 高三的时候时常做梦,有一次他梦到了自己高考结束,顺利地进入了大学。

但大学可不是那么好玩的,大学里面有很多课程要学习,一门课程需要学习一学期,而且很多课程都要求先

学某些前置课程,比如课程a 的前置课程是课程b,意思就是是学了课程b 才能学课程a。没有前置条件或

者前置课程已经学完的课程,可以任意选择并学习了,而且可以在同一学期同时学习多门课程,但令人烦恼

的是只能在每学期开学选课,一学期有且仅有这一次选课机会。更不幸的是,jyb 可能上的是假大学,假大学

的课程安排是有冲突的,即前置条件矛盾。现在学校给出了要学习的课程数量和学习课程的前置条件,jyb 想

知道他梦中上的是不是假大学,如果上的真大学,那么jyb 至少需要学习几学期才能学完所有课程呢?

Input

第1 行,1 个整数T,表示数据组数。接下来T 组数据,对于每组数据:

第1 行,2 个整数n;m,表示课程数量和前置课程条件数量。课程用1; 2; : : : ; n 编号。

接下来m 行,每行2 个整数u; v,表示课程u 的前置课程是v。

Output

对于每组数据:

若jyb 上的是假大学,则输出”BUAA”(不含双引号),否则输出至少需要几学期学习完所有课程。

Sample

study.in 

2

2 2

1 2

2 1

4 4

3 1

2 1

4 2

4 3
study.out

BUAA

3

Note

• 对于10% 的数据,1 n 10,1 m 10;

• 对于30% 的数据,1 n 103,1 m 103;

• 对于60% 的数据,1 n 104,1 m 105;

• 对于100% 的数据,1 T 5,1 n 105,1 m 2 105。

AC代码

#include <ctime>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define re return
#define clr(a,b) memset(a,b,s(a))
#define s(a)  sizeof(a)
#define up(i,m,n) for(int i=m;i<=n;i++)
#define down(i,m,n) for (int i=n;i>=m;i--)
using namespace std;
const int MAXN=100005,MAXM=2*MAXN-5;
int head[MAXN],indgr[MAXN];
int stack[MAXN],top=0;
int f[MAXN];
int I;
int n,m;
struct SKY{
int to;int pre;
SKY(){
to=pre=0;
}
}g[MAXM];
template <class T>
inline int read(T &x)
{
x = 0;
T flag = 1;
char ch = (char)getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = (char)getchar();
}
while(ch>='0' && ch<='9')
{
x = (x<<1) + (x<<3) + ch - '0';
ch = (char)getchar();
}
x *= flag;
return 1;
}

int ne=0;
inline void add(int x,int y)
{
ne++;
g[ne].to=y;
g[ne].pre=head[x];
head[x]=ne;
}
inline int tp()
{
top=0;
up(i,1,n)
if(!indgr[i])
{
stack[++top]=i;
f[i]=1;
}

while(top>0)
{
I++;
int u=stack[top--];
for (int i=head[u];i;i=g[i].pre)
{
int v=g[i].to;
indgr[v]--;f[v]=max(f[v],f[u]+1);
if(indgr[v]==0)
stack[++top]=v;
}
}
int maxx=-1;
up(i,1,n)
maxx=max(maxx,f[i]);
return I==n? maxx : -1 ;
}
inline int init()
{
I=0;
clr(head,0);
clr(stack,0);
clr(indgr,0);
clr(f,0);
ne=0;
read(n);read(m);
up(i,1,m)
{
int a,b;
read(a);read(b);
add(b,a);
indgr[a]++;
}
return tp();
}
int main()
{
freopen("study.in","r",stdin);
freopen("study.out","w",stdout);
int T;
read(T);
while(T--)
{
int ans=init();
ans!= -1 ? printf("%d\n",ans) : printf("%s\n","BUAA");
}
return 0;
}


Problem 2. Bomb

Input file: bomb.in

Output file: bomb.out

Time limit: 1 second

马上就要CKY 期待了很久的春节啦!每年过春节,CKY 最喜欢的一件娱乐活动就是玩炮仗!

现在CKY 有n 个炮仗要点燃,假定给出一个二维坐标系,CKY 清楚地知道每个炮仗的位置(xi; yi)。一个炮

仗的爆炸能够引爆其他炮仗,但每个炮仗的威力大小都不同,所以每个炮仗引爆其他炮仗的能力也不同。我

们用引爆半径ri 来具体衡量一个炮仗的威力。如果没被点燃的炮仗在会被引爆的炮仗的引爆范围内,那么也

会被点燃引爆。

同时点燃一个炮仗会消耗打火机ci 的燃料,CKY 想知道引爆所有的炮仗最少需要消耗多少打火机的燃料

Input

第1 行,1 个整数n,表示炮仗数量

接下来n 行,每行4 个整数xi, yi, ri,ci, 表示第i 个炮仗的位置(x; y),引爆半径ri,和点燃需要消耗的燃

料ci

Output

输出最少需要消耗的燃料

Sample

bomb.in 

5

0 0 1 5

1 1 1 6

0 1 1 7

3 0 2 10

5 0 1 4

bomb.out

15

Note

• 对于30% 的数据, 1 n 10,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: