标签:
★★☆ 输入文件:buss.in
输出文件:buss.out
简单对比
时间限制:1 s 内存限制:256 MB
5 6 1 2 2 3 3 4 4 1 2 5 5 2 1 0 0
1 2 3 4 5 1
题解:
很明显的缩点、重建图。重建图之后判断出度,没有出度的新点就可以设置站点。
AC代码:
#include<cstdio> #include<cstring> #include<vector> #include<stack> using namespace std; #define N 100010 int n,m,sd,pd,id[N],low[N],dfn[N]; bool mark[N]; stack<int>s; vector<int>grap[N]; void tarjan(int v){ low[v]=dfn[v]=++pd; mark[v]=1; s.push(v); for(int i=0;i<grap[v].size();i++){ int w=grap[v][i]; if(!dfn[w]){ tarjan(w); low[v]=min(low[v],low[w]); } else if(mark[w]){ low[v]=min(low[v],dfn[w]); } } int u; if(low[v]==dfn[v]){ sd++; do{ u=s.top(); s.pop(); id[u]=sd; mark[u]=0; }while(u!=v); } } int main(){ freopen("buss.in","r",stdin); freopen("buss.out","w",stdout); while(scanf("%d",&n)==1){ if(!n) break; scanf("%d",&m); if(n==1&&m==0){printf("1");continue;} sd=0;pd=0; memset(low,0,sizeof low); memset(dfn,0,sizeof dfn); memset(mark,0,sizeof mark); memset(id,0,sizeof id); while(!s.empty()) s.pop(); for(int i=1,x,y;i<=m;i++) scanf("%d%d",&x,&y),grap[x].push_back(y); for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); int in[N]={0},out[N]={0}; for(int i=1;i<=n;i++){ for(int j=0;j<grap[i].size();j++){ int k=grap[i][j]; if(id[i]!=id[k]){ in[id[k]]++; out[id[i]]++; } } } for(int i=1;i<=n;i++) if(!out[id[i]]) printf("%d ",i);putchar(‘\n‘); for(int i=1;i<=n;i++) grap[i].clear(); } return 0; }
标签:
原文地址:http://www.cnblogs.com/shenben/p/5838762.html