[机房考试] 图论 题解

来源:互联网 发布:隔壁老王的来历 知乎 编辑:程序博客网 时间:2024/06/04 18:29

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,
0 0
原创粉丝点击