P3119 [USACO15JAN]草鉴定Grass Cownoisseur
tarjan缩点,正反spfa,枚举边,更新最大值
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxn 1000000 4 #define inf 0x3f3f3f3f 5 int n,m,x[maxn],y[maxn],z,num,head[maxn],head2[maxn],tim,ans,tot,dis1[maxn],dis2[maxn],head3[maxn]; 6 int sumcol,dfn[maxn],low[maxn],sumedge,Stack[maxn],point[maxn],top,color[maxn],dis[maxn],tot2; 7 bool vis[maxn]; 8 struct Edge{ 9 int u,v,d,next; 10 }edge[maxn],edge2[maxn],edge3[maxn]; 11 12 inline void read(int &now) 13 { 14 char ch=getchar(); now=0; int f=1; 15 while(ch>'9'||ch<'0') { if(ch=='-') f*=-1; ch=getchar();} 16 while(ch>='0'&&ch<='9') now=now*10+ch-'0',ch=getchar(); 17 now*=f; 18 } 19 20 void add_edge(int u,int v) 21 { 22 edge[++num].v=v; 23 edge[num].next=head[u]; head[u]=num; 24 } 25 26 inline void ins(int u,int v) 27 { 28 edge2[++tot].u=u; 29 edge2[tot].v=v; 30 edge2[tot].next=head2[u]; 31 head2[u]=tot; 32 } 33 34 inline void ins2(int u,int v) 35 { 36 edge3[++tot2].u=u; 37 edge3[tot2].v=v; 38 edge3[tot2].next=head3[u]; 39 head3[u]=tot2; 40 } 41 42 int tarjan(int now) 43 { 44 dfn[now]=low[now]=++tim; 45 vis[now]=true; Stack[++top]=now; 46 for(int i=head[now];i;i=edge[i].next) 47 { 48 int t=edge[i].v; 49 if(vis[t]) low[now]=min(low[now],dfn[t]); 50 else if(!dfn[t]) tarjan(t),low[now]=min(low[now],low[t]); 51 } 52 if(low[now]==dfn[now]) 53 { 54 sumcol++,color[now]=sumcol,point[sumcol]++; 55 for(;Stack[top]!=now;top--) 56 color[Stack[top]]=sumcol,vis[Stack[top]]=false,point[sumcol]++; 57 vis[now]=false,top--; 58 } 59 } 60 61 inline void spfa(int s) 62 { 63 queue<int>que; 64 bool inq[maxn]; 65 for(int i=1;i<=sumcol;i++) dis[i]=-10000,inq[i]=false; 66 dis[s]=point[s]; inq[s]=1; 67 que.push(s); 68 while(!que.empty()) 69 { 70 int cur=que.front(); que.pop(); 71 for(int i=head2[cur];i;i=edge2[i].next) 72 { 73 int v=edge2[i].v; 74 if(dis[cur]+point[edge2[i].v]>dis[v]) 75 { 76 dis[v]=dis[cur]+point[edge2[i].v]; 77 if(!inq[v]) 78 { 79 inq[v]=1; 80 que.push(v); 81 } 82 } 83 } 84 inq[cur]=false; 85 } 86 } 87 88 inline void spfa2(int s) 89 { 90 queue<int>que; 91 bool inq[maxn]; 92 for(int i=1;i<=sumcol;i++) dis[i]=-10000,inq[i]=false; 93 dis[s]=point[s]; inq[s]=1; 94 que.push(s); 95 while(!que.empty()) 96 { 97 int cur=que.front(); que.pop(); 98 for(int i=head3[cur];i;i=edge3[i].next) 99 { 100 int v=edge3[i].v; 101 if(dis[cur]+point[edge3[i].v]>dis[v]) 102 { 103 dis[v]=dis[cur]+point[edge3[i].v]; 104 if(!inq[v]) 105 { 106 inq[v]=1; 107 que.push(v); 108 } 109 } 110 } 111 inq[cur]=false; 112 } 113 } 114 115 int AC() 116 { 117 read(n); read(m); 118 for(int i=1;i<=m;i++) 119 { 120 read(x[i]); read(y[i]); 121 add_edge(x[i],y[i]); 122 } 123 for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); 124 for(int u=1;u<=n;u++) 125 for(int i=head[u];i;i=edge[i].next) 126 if(color[u]!=color[edge[i].v]) 127 { 128 ins(color[u],color[edge[i].v]); 129 ins2(color[edge[i].v],color[u]); 130 } 131 spfa(color[1]); 132 for(int i=1;i<=sumcol;i++) dis1[i]=dis[i]; 133 spfa2(color[1]); 134 for(int i=1;i<=sumcol;i++) dis2[i]=dis[i]; 135 for(int i=1;i<=m;i++) 136 { 137 if(dis1[color[y[i]]]+dis2[color[x[i]]]>ans) 138 ans=dis1[color[y[i]]]+dis2[color[x[i]]]; 139 } 140 printf("%d ",ans-point[color[1]]); 141 return 0; 142 } 143 144 int IwantAC = AC(); 145 146 int main(){;}