P1726 上白泽慧音
题目链接:P1726
题目大意:
给一个有向图,找出最大的强连通分量,如果有多个最大的强连通分量,输出序号字典序最小的。
解题思路:
tarjan模板题,洛谷给成蓝题感觉难度给高了。找字典序最小的时候,如果有两个强连通分量大小相同,则输出代表元序号最小的那一个scc,因为不可能有两个强连通分量的代表元相同,假如有的话,那这两个强连通分量可以合并构成一个更大的scc。
参考代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <vector> 7 #define N 50010 8 using namespace std; 9 /* 10 head,nxt,to 链式前向星存图 11 belong 强连通分量代表元 12 col 每个强连通分量的大小 13 dfn,low: tarjan算法所用数组 14 s:tarjan算法手写栈 15 vis:tarjan时标记是否访问过 16 */ 17 int cnt,id,tot; // cnt为链星的标号,id为dfn,low的标号,tot为栈s的标号 18 int head[N],nxt[N],to[N],belong[N],dfn[N],low[N],s[N],col[N]; 19 bool vis[N]; 20 21 inline int read() 22 { 23 int x = 0, y = 1; char c = getchar(); 24 while(c < '0' || c > '9') {if(c == '-') y = -1; c = getchar();} 25 while(c >= '0' && c <= '9') x = x*10+c-'0', c = getchar(); 26 return x*y; 27 } 28 // 链星加边 29 void add(int u, int v) 30 { 31 nxt[++cnt] = head[u]; 32 head[u] = cnt; 33 to[cnt] = v; 34 } 35 // tarjan 36 void tarjan(int u) 37 { 38 vis[u] = true; 39 dfn[u] = low[u] = ++id; 40 s[++tot] = u; 41 for(int i = head[u]; ~i; i = nxt[i]) 42 { 43 int v = to[i]; 44 if(!dfn[v]) 45 { 46 tarjan(v); 47 low[u] = min(low[u],low[v]); 48 } else if(vis[v]) low[u] = min(low[u],low[v]); 49 } 50 if(dfn[u] == low[u]) 51 { 52 vis[u] = false; 53 belong[u] = u; 54 col[u]++; 55 while(s[tot] != u) 56 { 57 vis[s[tot]] = false; 58 belong[s[tot]] = u; 59 col[u]++; 60 tot--; 61 } 62 tot--; 63 } 64 } 65 // 初始化 66 void init() 67 { 68 cnt = -1; 69 tot = id = 0; 70 memset(vis,false,sizeof(vis)); 71 memset(head,-1,sizeof(head)); 72 } 73 int main() 74 { 75 init(); 76 // maxx,maxn分别用来存最大的scc的大小以及最大的scc的代表元 77 int maxx = -1; 78 int maxn; 79 int n,m; 80 int u,v,t; 81 n = read(); 82 m = read(); 83 for(int i = 0; i < m; i++) 84 { 85 u = read(); 86 v = read(); 87 t = read(); 88 if(t == 1) 89 { 90 add(u,v); 91 } else if(t == 2) { // 双向边,加两次 92 add(u,v); 93 add(v,u); 94 } 95 } 96 // 保证图不连通时,每个点都tarjan到了 97 for(int i = 1; i <= n; i++) 98 { 99 if(!dfn[i]) 100 tarjan(i); 101 } 102 // 找最大的scc同时找字典序最小的 103 for(int i = 1; i <= n; i++) 104 { 105 if(col[belong[i]] > maxx) 106 { 107 maxx = col[belong[i]]; 108 maxn = belong[i]; 109 } else if(col[belong[i]] == maxx && maxn > belong[i]) { 110 maxn = belong[i]; 111 } 112 } 113 // 输出 114 printf("%d\n",maxx); 115 for(int i = 1; i <= n; i++) 116 { 117 if(belong[i] == maxn) 118 printf("%d ",i); 119 } 120 return 0; 121 }

浙公网安备 33010602011771号