• 【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);
    }
  • 相关阅读:
    mac下webstorm自动编译typescript配置
    [转]Golang 中使用 JSON 的小技巧
    Element-UI 框架 el-scrollbar 组件
    npm读取config配置的优先级(yarn同理)
    win, mac, linux 默认系统缓存目录
    yum离线安装rpm包
    常见网络摄像机(摄像头)的端口及RTSP地址
    sed命令在mac和linux下的区别
    canvas笔记备忘
    shell脚本:批量修改文件名(添加/删除文件名中字符)
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11298468.html
Copyright © 2020-2023  润新知