• 洛谷 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
  • 相关阅读:
    VC++学习(16):线程同步与异步套接字
    VC++学习(15):多线程
    VC++学习(12):文件操作
    VC++学习(10):绘图控制
    VC++学习(13):文档串行化
    VC++学习(11):图形的保存和重绘
    VC++学习(18):Active控件
    四大数据库的比较(SQL Server、Oracle、Sybase和DB2)
    Gridview中二级联动
    VS 2008中PDA开发环境的相关配置
  • 原文地址:https://www.cnblogs.com/chen74123/p/7496605.html
Copyright © 2020-2023  润新知