标签:分享 clu 联通 names tmp logs namespace stream 相同
题目大意:
给一个有向图
求一个最大的强连通分量,输出这个强连通分量里的所有元素
若两个联通分量内点数相同 则输出字典序小的那个
思路:
直接tarjan
对每个连通分量,求一下最小点,然后判断字典序就行了
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<set> 8 #include<map> 9 #include<vector> 10 #include<stack> 11 #include<queue> 12 #define ll long long 13 #define inf 2147383611 14 #define MAXN 100100 15 #define MOD 5050 16 using namespace std; 17 inline int read() 18 { 19 int x=0,f=1; 20 char ch;ch=getchar(); 21 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 22 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 23 return x*f; 24 } 25 int n,m,next[MAXN*2],first[MAXN],to[MAXN*2],cnt; 26 int scc,dfn[MAXN],low[MAXN],bl[MAXN],stp,num[MAXN],minn[MAXN]; 27 bool vis[MAXN]; 28 int st[MAXN],top; 29 void add(int u,int v) {next[++cnt]=first[u],first[u]=cnt,to[cnt]=v;} 30 void tarjan(int x) 31 { 32 low[x]=dfn[x]=++stp,st[++top]=x,vis[x]=1; 33 for(int i=first[x];i;i=next[i]) 34 { 35 if(!dfn[to[i]]) 36 { 37 tarjan(to[i]);low[x]=min(low[x],low[to[i]]); 38 } 39 else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]); 40 } 41 if(low[x]==dfn[x]) 42 { 43 scc++,minn[scc]=inf; 44 while(st[top+1]!=x) minn[scc]=min(st[top],minn[scc]),bl[st[top]]=scc,num[scc]++,vis[st[top]]=0,top--; 45 } 46 } 47 int main() 48 { 49 n=read(),m=read(); 50 int t,a,b; 51 while(m--) 52 { 53 a=read(),b=read(),t=read(); 54 if(t==1) add(a,b); 55 else {add(a,b);add(b,a);} 56 } 57 for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); 58 int tmp=0,k; 59 for(int i=1;i<=scc;i++) if(num[i]>=tmp||(num[i]==tmp&&minn[i]<minn[tmp])) tmp=num[i],k=i; 60 printf("%d\n",tmp); 61 for(int i=1;i<=n;i++) if(bl[i]==k) printf("%d ",i); 62 }
标签:分享 clu 联通 names tmp logs namespace stream 相同
原文地址:http://www.cnblogs.com/yyc-jack-0920/p/7755233.html