• 【POI2014】RAJ-Rally


    题面

    https://www.luogu.org/problem/P3573

    题解

    拓扑排序神仙题。

    因为是$DAG$,所以拓扑排序搞出拓扑序。

    在正反两遍$dp$搞出$f[x]$和$g[x]$

    再用类似扫描线的方法更新好了。

    实现时传承$yyb$的题解,用了可删堆,实现方法和可删除的$AC$自动机一样,也可以用线段树(可能要在线段树上二分跑答案)

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 500500
    #define ri register int
    using namespace std;
    
    int n,m,ru[N],tup[N],f[N],g[N];
    vector<int> to[N],dt[N];
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    struct keshandui {
      priority_queue<int> a,b;
      void push(int x) {
        a.push(x);
      }
      void del(int x) {
        b.push(x);
      }
      int top() {
        while (!a.empty() && !b.empty() && a.top()==b.top()) a.pop(),b.pop();
        return a.top();
      }
    } q;
    
    int main(){
      n=read(); m=read();
      for (ri i=1;i<=m;i++) {
        int u=read(),v=read();
        to[u].push_back(v); dt[v].push_back(u);
        ru[v]++;
      }
      queue<int> Q;
      for (ri i=1;i<=n;i++) if (!ru[i]) Q.push(i);
      int cc=0;
      while (!Q.empty()) {
        int x=Q.front(); Q.pop();
        tup[++cc]=x;
        for (ri i=0;i<to[x].size();i++) {
          int y=to[x][i];
          ru[y]--;
          if (!ru[y]) Q.push(y);
        }
      }
      for (ri i=1;i<=n;i++) {
        int x=tup[i];
        for (ri j=0;j<to[x].size();j++) if (f[x]+1>f[to[x][j]]) f[to[x][j]]=f[x]+1;
      }
      for (ri i=n;i>=1;i--) {
        int x=tup[i];
        for (ri j=0;j<to[x].size();j++) if (g[to[x][j]]+1>g[x]) g[x]=g[to[x][j]]+1;
      }
      for (ri i=1;i<=n;i++) q.push(g[tup[i]]);
      int ans1=n+1,ans2=-1;
      for (ri i=1;i<=n;i++) {
        int x=tup[i];
        q.del(g[x]);
        for (ri j=0;j<dt[x].size();j++) q.del(f[dt[x][j]]+g[x]+1);
        if (q.top()<ans1) ans1=q.top(),ans2=x;
        q.push(f[x]);
        for (ri j=0;j<to[x].size();j++) q.push(f[x]+g[to[x][j]]+1);
      }
      printf("%d %d
    ",ans2,ans1);
    }
  • 相关阅读:
    CSS团队协作规范
    百度前端学院-基础学院-第四课
    百度前端学院-基础学院-第三课
    百度前端学院-基础学院-第二课
    vue(三)-父子组件通信
    setTimeout()与clearTimeout()
    vue(二)-父子组件语法
    vue(一)使用vue-cli搭建项目
    CSS table-layout 属性
    git学习
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11298468.html
Copyright © 2020-2023  润新知