Problem: 八中教室的灯
Time Limit: 10 Sec Memory Limit: 128 MB
Description
八中一共有被用M条双向道路连接的N个教室(1<=N,M<=3000)。为了关闭整个八中,master wen 计划每一次关闭掉一个教室。当一个教室被关闭了,所有的连接到这个教室的道路都会被关闭,而且再也不能够被使用。master wen现在正感兴趣于知道在每一个时间(这里的“时间”指在每一次关闭教室之前的时间)时他的八中是否是“全连通的”——也就是说从任意的一个开着的教室开始,能够到达另外的一个教室。注意自从某一个时间之后,可能整个八中都开始不会是“全连通的”。
Input
- 第一行给出数字N,M,代表有N个教室,M条边,1<=N,M<=3000
- 接下来N行来用描述教室之间相连的情况
- 接下来N行,每行给出一个数字,代表关闭了哪个教室的灯
Output
- 输出N行,每行输出"YES"或"NO".
- 第一行输出最开始时整个八中是不是连通的
- 后面的N-1用来描述关闭某个教室的灯后,八中是不是连通的。
Sample Input
4 3
1 2
2 3
3 4
3
4
1
2
Sample Output
YES
NO
YES
YES
代码如下
/* -std=c99 */
#include<stdio.h>
#include<string.h>
int n,m;
int tot,ans,sum;
int pre[6050],now[6050],son[6050],mp[3050],off[3050];
void put(int a,int b) {
pre[++sum]=now[a];
now[a]=sum;
son[sum]=b;
}
int dfs(int u) {
int s=0;
mp[u]=1;
for(int i=now[u]; i; i=pre[i]) {
int k=son[i];
if(!mp[k]&&!off[k]) {
s+=dfs(k);
}
}
return s+1;
}
int main() {
scanf("%d %d",&n,&m);
for(int i=1,x,y; i<=m; i++) {
scanf("%d%d",&x,&y);
put(x,y),put(y,x);
}
ans=dfs(1);
if(ans==n)
printf("YES
");
else printf("NO
");
for(int i=1,take; i<=n-1; i++) {
memset(mp,0,sizeof(mp));
scanf("%d",&take);
off[take]=1;
for(int j=1; j<=n; j++) {
if(!off[j]) {
tot=j;
break;
}
}
ans=dfs(tot);
if(ans==n-i)printf("YES
");
else printf("NO
");
}
}