• [Usaco2015 Jan]Grass Cownoisseur 图论 tarjan spfa


    先缩点,对于缩点后的DAG,正反跑spfa,枚举每条边进行翻转即可

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    using namespace std;
    struct pp{
        struct edge{
            int u,v,w,next;
        }ed[200005];
        int e,head[100005];
        pp(){
            e=1;
            memset(head,0,sizeof head);
        }
        void add(int u,int v,int w){
            ed[e].u=u; ed[e].v=v; ed[e].w=w;
            ed[e].next=head[u]; head[u]=e++;
        }
    };
     
    pp orgp,newp,newf;
    int dfn[100005],low[100005],q[100005];
    int top=0,tot=0,id[100005],size[100005];
    bool bo[100005];
     
    void tarjan(int x){
        dfn[x]=low[x]=++top;
        q[top]=x; bo[x]=1;
        for(int i=orgp.head[x];i;i=orgp.ed[i].next){
            int v=orgp.ed[i].v;
            if(!dfn[v]){
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(bo[v])
                low[x]=min(low[x],dfn[v]);
        }
        if(dfn[x]==low[x]){
            int y; tot++;
            do{
                y=q[top--];
                bo[y]=0;
                id[y]=tot;
                size[tot]++;
            }while(y!=x);
        }
    }
     
    int dis[100005][2];
     
    void spfa(pp &ppp,int x,int t){
        memset(bo,0,sizeof bo);
        queue<int > q; q.push(x); 
        dis[x][t]=size[x]; int now,v,w;
        while(!q.empty())
        {
            now=q.front(); q.pop(); bo[now]=0;
            for(int i=ppp.head[now];i;i=ppp.ed[i].next)
            {
                v=ppp.ed[i].v; w=ppp.ed[i].w;
                if(dis[v][t]<dis[now][t]+w){
                    dis[v][t]=dis[now][t]+w;
                    if(!bo[v]){
                        bo[v]=1;
                        q.push(v);
                    }
                }
            }
        }
    }
     
    int n,m;
     
    int main()
    {
        //freopen("cown.in","r",stdin);
        //freopen("cown.out","w",stdout);
        scanf("%d%d",&n,&m);
        int u,v;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            orgp.add(u,v,1);
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i])
                tarjan(i);
        for(int i=1;i<=m;i++){
            if(id[orgp.ed[i].u]!=id[orgp.ed[i].v]){
                newp.add(id[orgp.ed[i].u],id[orgp.ed[i].v],size[id[orgp.ed[i].v]]);
                newf.add(id[orgp.ed[i].v],id[orgp.ed[i].u],size[id[orgp.ed[i].u]]);
            }
        }
        int ans=-0x7fffffff;
        memset(dis,-0x3f,sizeof dis);
        spfa(newp,id[1],0);
        spfa(newf,id[1],1);
        for(int i=1;i<newp.e;i++)
        {
            u=newp.ed[i].u;
            v=newp.ed[i].v;
            ans=max(ans,dis[u][1]+dis[v][0]-size[id[1]]);
        }
        printf("%d
    ",ans);
    }
    打的好蠢啊QAQ

  • 相关阅读:
    Linux内核中锁机制之RCU、大内核锁
    Linux内核中锁机制之完成量、互斥量
    Linux内核中锁机制之信号量、读写信号量
    Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁
    Linux内核中锁机制之原子操作、自旋锁
    Linux内核jiffies简介
    pdflush机制
    ext2文件系统
    从ext2文件系统上读出超级块
    ext2磁盘布局
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746755.html
Copyright © 2020-2023  润新知