P3119-[USACO15JAN]草鉴定Grass Cownoisseur
1 #include <iostream> 2 #include <vector> 3 #include <queue> 4 #include <cstring> 5 using namespace std; 6 #define _for(i,a,b) for(int i = (a);i < b;i ++) 7 #define _rep(i,a,b) for(int i = (a);i > b;i --) 8 #define INF 0x3f3f3f3f 9 #define pb push_back 10 #define maxn 100039 11 typedef long long ll; 12 typedef pair<int,int> P;//first 是最短距离,second 是顶点编号 13 inline ll read() 14 { 15 ll ans = 0; 16 char ch = getchar(), last = ' '; 17 while(!isdigit(ch)) last = ch, ch = getchar(); 18 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); 19 if(last == '-') ans = -ans; 20 return ans; 21 } 22 inline void write(ll x) 23 { 24 if(x < 0) x = -x, putchar('-'); 25 if(x >= 10) write(x / 10); 26 putchar(x % 10 + '0'); 27 } 28 int V,E; 29 int ver[maxn],Next[maxn],head[maxn],dfn[maxn],low[maxn]; 30 int Gver[2][maxn],GNext[2][maxn],Ghead[2][maxn],Gtot[2]; 31 int stack[maxn],ins[maxn],c[maxn]; 32 int dis[2][maxn]; 33 vector<int> scc[maxn]; 34 int tot,top,cnt,nm; 35 void addori(int x,int y) 36 { 37 ver[++tot] = y,Next[tot] = head[x],head[x] = tot; 38 } 39 void tarjan(int x) 40 { 41 dfn[x] = low[x] = ++nm; 42 stack[++top] = x,ins[x] = 1; 43 for(int i = head[x]; i; i = Next[i]) 44 { 45 int y = ver[i]; 46 if(!dfn[y]) 47 { 48 tarjan(y); 49 low[x] = min(low[x],low[y]); 50 } 51 else if(ins[y]) 52 low[x] = min(low[x],dfn[y]); 53 } 54 if(dfn[x] == low[x]) 55 { 56 cnt ++; 57 int y; 58 do 59 { 60 y = stack[top --],ins[y] = 0; 61 c[y] = cnt,scc[cnt].pb(y); 62 } 63 while(x != y); 64 } 65 } 66 void addAft(int x,int y,int num) 67 { 68 Gver[num][++Gtot[num]] = y; 69 GNext[num][Gtot[num]] = Ghead[num][x]; 70 Ghead[num][x] = Gtot[num]; 71 } 72 void Shrink() 73 { 74 _for(i,1,V+1) 75 if(!dfn[i]) 76 tarjan(i); 77 78 _for(x,1,V+1) 79 for(int i = head[x]; i; i = Next[i]) 80 { 81 int y = ver[i]; 82 if(c[x]==c[y]) continue; 83 addAft(c[x],c[y],0); 84 addAft(c[y],c[x],1); 85 } 86 } 87 void shortest_path(int k,int num) 88 { 89 dis[num][k] = scc[k].size(); 90 queue<int> Q; 91 Q.push(k); 92 while(!Q.empty()) 93 { 94 int now = Q.front(); 95 Q.pop(); 96 for(int i = Ghead[num][now]; i; i = GNext[num][i]) 97 { 98 int v = Gver[num][i]; 99 if(dis[num][v] < dis[num][now] + scc[v].size()) 100 { 101 dis[num][v] = dis[num][now] + scc[v].size(); 102 if(!ins[v]) 103 Q.push(v),ins[v] = 1; 104 } 105 } 106 ins[now] = 0; 107 } 108 } 109 110 int main() 111 { 112 // freopen("testdata.in","r+",stdin); 113 V = read(),E = read(); 114 _for(i,0,E) 115 { 116 int a = read(); 117 int b = read(); 118 addori(a,b); 119 } 120 Shrink(); 121 shortest_path(c[1],0); 122 shortest_path(c[1],1); 123 // cout << dis[0][99] << endl; 124 int ans = scc[c[1]].size(); 125 _for(i,1,V+1) 126 { 127 if(!ins[c[i]] && dis[0][c[i]]) 128 { 129 int now = c[i]; 130 ins[now] = 1; 131 for(int u = Ghead[1][now]; u; u = GNext[1][u]) 132 { 133 int v = Gver[1][u]; 134 if(!dis[1][v]) continue; 135 ans = max(ans,dis[0][now] + dis[1][v] - (int)scc[c[1]].size()); 136 } 137 } 138 } 139 write(ans); 140 return 0; 141 }