记录编号 |
583460 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[顾研NOIP] 旅游电车 |
最终得分 |
100 |
用户昵称 |
┭┮﹏┭┮ |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.231 s |
提交时间 |
2023-10-14 18:11:57 |
内存使用 |
3.76 MiB |
显示代码纯文本
- #include <bits/stdc++.h>
- using namespace std;
- //tarjan求强连通分量
- //一个景区可以被设置成车站,当且仅当对于任意一个从该景区出发所能到达的景区,均至少有一条路可回到该景区
- const int N = 5e3+10,M = 5e4+10;
- int n,m;
- struct made{
- int ver,nx;
- }e[M];
- int hd[N],tot,cnt,num,top;
- int low[N],dfn[N],color[N],st[N];
- int v[N];
- vector<int>ans;
- void first(){
- cnt = tot = num = top = 0;
- memset(e,0,sizeof(e));
- memset(low,0,sizeof(low));
- memset(dfn,0,sizeof(dfn));
- memset(v,0,sizeof(v));
- memset(color,0,sizeof(color));
- memset(st,0,sizeof(st));
- memset(hd,0,sizeof(hd));
- }//初始化
- void add(int x,int y){
- tot++;
- e[tot].ver = y,e[tot].nx = hd[x],hd[x] = tot;
- }
- void tarjan(int x){
- low[x] = dfn[x] = ++cnt;
- st[++top] = x,v[x] = 1;
- for(int i = hd[x];i;i = e[i].nx){
- int y = e[i].ver;
- if(!dfn[y])tarjan(y),low[x] = min(low[x],low[y]) ;
- else if(v[y])low[x] = min(low[x],dfn[y]);
- }
- if(low[x] == dfn[x]){
- num++;int y = 0;
- do{
- y = st[top--];
- v[y] = 0,color[y] = num;
- }while(x != y);
- }
- }
- void check(int x){
- for(int i = hd[x];i;i = e[i].nx){
- int y = e[i].ver;
- if(color[x] != color[y])v[color[x]]++;
- }
- }//一个景区可以被设置成车站,当且仅当对于任意一个从该景区出发所能到达的景区,均至少有一条路可回到该景区
- int main(){
- freopen("buss.in","r",stdin);
- freopen("buss.out","w",stdout);
- while(1){
- scanf("%d",&n);
- if(!n)break;
- scanf("%d",&m);
- first();
- for(int i = 1;i <= m;i++){
- int x,y;
- scanf("%d%d",&x,&y);
- add(x,y);
- }
- for(int i = 1;i <= n;i++)
- if(!color[i])tarjan(i);
- memset(v,0,sizeof(v));
- for(int i = 1;i <= n;i++)check(i);
- //按编号从小到大列出
- for(int i = 1;i <= n;i++)
- if(!v[color[i]])printf("%d ",i);
- printf("\n");
- }
-
-
-
- return 0;
-
- }