标签:turn 题目 false names ack memset mes scan log
题目链接:https://vjudge.net/problem/UVA-11324
题解:
代码一:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const double EPS = 1e-8; 16 const int INF = 2e9; 17 const LL LNF = 2e18; 18 const int MAXM = 5e4+10; 19 const int MAXN = 1e3+10; 20 21 struct Edge 22 { 23 int to, next; 24 }edge[MAXM], edge0[MAXM]; //edge为初始图, edge0为重建图 25 int tot, head[MAXN], tot0, head0[MAXN]; 26 27 int Index, dfn[MAXN], low[MAXN]; 28 int top, Stack[MAXN], instack[MAXN]; 29 int scc, belong[MAXN], num[MAXN]; 30 int dp[MAXN]; 31 32 void addedge(int u, int v, Edge edge[], int head[], int &tot) 33 { 34 edge[tot].to = v; 35 edge[tot].next = head[u]; 36 head[u] = tot++; 37 } 38 39 void Tarjan(int u) 40 { 41 dfn[u] = low[u] = ++Index; 42 Stack[top++] = u; 43 instack[u] = true; 44 for(int i = head[u]; i!=-1; i = edge[i].next) 45 { 46 int v = edge[i].to; 47 if(!dfn[v]) 48 { 49 Tarjan(v); 50 low[u] = min(low[u], low[v]); 51 } 52 else if(instack[v]) 53 low[u] = min(low[u], dfn[v]); 54 } 55 56 if(dfn[u]==low[u]) 57 { 58 int v; 59 scc++; 60 do 61 { 62 v = Stack[--top]; 63 instack[v] = false; 64 belong[v] = scc; 65 num[scc]++; 66 }while(v!=u); 67 } 68 } 69 70 int dfs(int u, int pre) 71 { 72 if(dp[u]!=-1) return dp[u]; 73 dp[u] = num[u]; 74 for(int i = head0[u]; i!=-1; i = edge0[i].next) 75 { 76 int v = edge0[i].to; 77 if(v==pre) continue; 78 dp[u] = max(dp[u], num[u]+dfs(v, u)); 79 } 80 return dp[u]; 81 } 82 83 void init() 84 { 85 tot = tot0 = 0; 86 memset(head, -1, sizeof(head)); 87 memset(head0, -1, sizeof(head0)); 88 89 Index = top = 0; 90 memset(dfn, 0, sizeof(dfn)); 91 memset(low, 0, sizeof(low)); 92 memset(instack, 0, sizeof(instack)); 93 94 scc = 0; 95 memset(num, 0, sizeof(num)); 96 memset(dp, -1, sizeof(dp)); 97 } 98 99 int main() 100 { 101 int n, m, T; 102 scanf("%d", &T); 103 while(T--) 104 { 105 scanf("%d%d", &n, &m); 106 init(); 107 for(int i = 1; i<=m; i++) 108 { 109 int u, v; 110 scanf("%d%d", &u, &v); 111 addedge(u, v, edge, head, tot); 112 } 113 114 for(int i = 1; i<=n; i++) 115 if(!dfn[i]) 116 Tarjan(i); 117 118 for(int u = 1; u<=n; u++) //重建建图 119 for(int i = head[u]; i!=-1; i = edge[i].next) 120 { 121 int tmpu = belong[u]; 122 int tmpv = belong[edge[i].to]; 123 if(tmpu!=tmpv) 124 addedge(tmpu, tmpv, edge0, head0, tot0); 125 } 126 127 int ans = 0; 128 for(int i = 1; i<=scc; i++) 129 if(dp[i]==-1) 130 ans = max(ans, dfs(i, i)); 131 132 printf("%d\n", ans); 133 } 134 }
代码二:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const double EPS = 1e-8; 16 const int INF = 2e9; 17 const int MAXM = 5e4+10; 18 const int MAXN = 1e3+10; 19 20 struct Edge 21 { 22 int to, next; 23 }edge[MAXM]; //edge为初始图, edge0为重建图 24 int tot, head[MAXN]; 25 vector<int>g[MAXN]; 26 27 int Index, dfn[MAXN], low[MAXN]; 28 int top, Stack[MAXN], instack[MAXN]; 29 int scc, belong[MAXN], num[MAXN]; 30 int dp[MAXN]; 31 32 void addedge(int u, int v) 33 { 34 edge[tot].to = v; 35 edge[tot].next = head[u]; 36 head[u] = tot++; 37 } 38 39 void Tarjan(int u) 40 { 41 dfn[u] = low[u] = ++Index; 42 Stack[top++] = u; 43 instack[u] = true; 44 for(int i = head[u]; i!=-1; i = edge[i].next) 45 { 46 int v = edge[i].to; 47 if(!dfn[v]) 48 { 49 Tarjan(v); 50 low[u] = min(low[u], low[v]); 51 } 52 else if(instack[v]) 53 low[u] = min(low[u], dfn[v]); 54 } 55 56 if(dfn[u]==low[u]) 57 { 58 int v; 59 scc++; 60 do 61 { 62 v = Stack[--top]; 63 instack[v] = false; 64 belong[v] = scc; 65 num[scc]++; 66 }while(v!=u); 67 } 68 } 69 70 int dfs(int u, int pre) 71 { 72 if(dp[u]!=-1) return dp[u]; 73 dp[u] = num[u]; 74 for(int i = 0; i<g[u].size(); i++) 75 { 76 int v = g[u][i]; 77 if(v==pre) continue; 78 dp[u] = max(dp[u], num[u]+dfs(v, u)); 79 } 80 return dp[u]; 81 } 82 83 void init(int n) 84 { 85 tot = 0; 86 memset(head, -1, sizeof(head)); 87 88 Index = top = 0; 89 memset(dfn, 0, sizeof(dfn)); 90 memset(low, 0, sizeof(low)); 91 memset(instack, 0, sizeof(instack)); 92 93 scc = 0; 94 memset(num, 0, sizeof(num)); 95 memset(dp, -1, sizeof(dp)); 96 for(int i = 1; i<=n; i++) 97 g[i].clear(); 98 } 99 100 int main() 101 { 102 int n, m, T; 103 scanf("%d", &T); 104 while(T--) 105 { 106 scanf("%d%d", &n, &m); 107 init(n); 108 for(int i = 1; i<=m; i++) 109 { 110 int u, v; 111 scanf("%d%d", &u, &v); 112 addedge(u, v); 113 } 114 115 for(int i = 1; i<=n; i++) 116 if(!dfn[i]) 117 Tarjan(i); 118 119 for(int u = 1; u<=n; u++) //重建建图 120 for(int i = head[u]; i!=-1; i = edge[i].next) 121 { 122 int tmpu = belong[u]; 123 int tmpv = belong[edge[i].to]; 124 if(tmpu!=tmpv) 125 g[tmpu].push_back(tmpv); 126 } 127 128 int ans = 0; 129 for(int i = 1; i<=scc; i++) 130 if(dp[i]==-1) 131 ans = max(ans, dfs(i, i)); 132 133 printf("%d\n", ans); 134 } 135 }
代码三:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const double EPS = 1e-8; 16 const int INF = 2e9; 17 const int MAXN = 1e3+10; 18 19 vector<int>G[MAXN], g[MAXN]; 20 21 int Index, dfn[MAXN], low[MAXN]; 22 int top, Stack[MAXN], instack[MAXN]; 23 int scc, belong[MAXN], num[MAXN]; 24 int dp[MAXN]; 25 26 void Tarjan(int u) 27 { 28 dfn[u] = low[u] = ++Index; 29 Stack[top++] = u; 30 instack[u] = true; 31 for(int i = 0; i<G[u].size(); i++) 32 { 33 int v = G[u][i]; 34 if(!dfn[v]) 35 { 36 Tarjan(v); 37 low[u] = min(low[u], low[v]); 38 } 39 else if(instack[v]) 40 low[u] = min(low[u], dfn[v]); 41 } 42 43 if(dfn[u]==low[u]) 44 { 45 int v; 46 scc++; 47 do 48 { 49 v = Stack[--top]; 50 instack[v] = false; 51 belong[v] = scc; 52 num[scc]++; 53 }while(v!=u); 54 } 55 } 56 57 int dfs(int u, int pre) 58 { 59 if(dp[u]!=-1) return dp[u]; 60 dp[u] = num[u]; 61 for(int i = 0; i<g[u].size(); i++) 62 { 63 int v = g[u][i]; 64 if(v==pre) continue; 65 dp[u] = max(dp[u], num[u]+dfs(v, u)); 66 } 67 return dp[u]; 68 } 69 70 void init(int n) 71 { 72 Index = top = 0; 73 memset(dfn, 0, sizeof(dfn)); 74 memset(low, 0, sizeof(low)); 75 memset(instack, 0, sizeof(instack)); 76 77 scc = 0; 78 memset(num, 0, sizeof(num)); 79 memset(dp, -1, sizeof(dp)); 80 for(int i = 1; i<=n; i++) 81 { 82 G[i].clear(); 83 g[i].clear(); 84 } 85 } 86 87 int main() 88 { 89 int n, m, T; 90 scanf("%d", &T); 91 while(T--) 92 { 93 scanf("%d%d", &n, &m); 94 init(n); 95 for(int i = 1; i<=m; i++) 96 { 97 int u, v; 98 scanf("%d%d", &u, &v); 99 G[u].push_back(v); 100 } 101 102 for(int i = 1; i<=n; i++) 103 if(!dfn[i]) 104 Tarjan(i); 105 106 for(int u = 1; u<=n; u++) //重建建图 107 for(int i = 0; i<G[u].size(); i++) 108 { 109 int tmpu = belong[u]; 110 int tmpv = belong[G[u][i]]; 111 if(tmpu!=tmpv) 112 g[tmpu].push_back(tmpv); 113 } 114 115 int ans = 0; 116 for(int i = 1; i<=scc; i++) 117 if(dp[i]==-1) 118 ans = max(ans, dfs(i, i)); 119 120 printf("%d\n", ans); 121 } 122 }
UVA11324 The Largest Clique —— 强连通分量 + 缩点 + DP
标签:turn 题目 false names ack memset mes scan log
原文地址:http://www.cnblogs.com/DOLFAMINGO/p/7820041.html