洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur

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(){;}
View Code
原文地址:https://www.cnblogs.com/chen74123/p/7496605.html