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 }
原文地址:https://www.cnblogs.com/Asurudo/p/11612331.html