zoukankan      html  css  js  c++  java
  • 【yLOI2018】锦鲤抄

    题面

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

    题解

    为了带入氛围还把$QQ$音乐里的《锦鲤抄》点开听了听。

    让我们想想删除的顺序是什么样子的:最优的顺序一定是从拓扑序最大的点倒着删,删到拓扑序最小的点。

    其中有入度的强连通分量可以全都删完(最后通过“入度”退回拓扑序小的强连通分量)如果最后一个了,就必须留一个点。

    贪心即可。

    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 500500
    #define M 2000500
    #define mod 1000000007
    #define ri register int
    
    using namespace std;
    
    inline int read() {
      int ret=0; char ch=getchar();
      while (ch<'0' || ch>'9') ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return ret;
    }
    
    stack<int> s; vector<int> to[N];
    int dfn[N],low[N],a[N],bel[N],id[N];
    int n,m,k,u[M],v[M],sc=0,vc=0,ins[N],siz[N];
    
    void tarjan(int x) {
      dfn[x]=low[x]=++sc; s.push(x); ins[x]=1;
      for (ri i=0;i<to[x].size();i++) {
        int y=to[x][i];
        if (!dfn[y]) {
          tarjan(y);
          low[x]=min(low[x],low[y]);
        }
        else {
          if (ins[y]) low[x]=min(low[x],dfn[y]);
        }
      }
      if (low[x]==dfn[x]) {
        ++vc;
        while (1) {
          int t=s.top(); s.pop(); ins[t]=0;
          bel[t]=vc;
          siz[vc]++;
          if (t==x) break;
        }
      }
    }
    
    bool cmp(int x,int y) {
      return a[x]>a[y];
    }
    
    int main() {
      n=read(); m=read(); k=read();
      for (ri i=1;i<=n;i++) a[i]=read();
      for (ri i=1;i<=m;i++) {
        u[i]=read(); v[i]=read();
        to[u[i]].push_back(v[i]);
      }
      for (ri i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
      for (ri i=1;i<=m;i++) {
        if (bel[u[i]]!=bel[v[i]]) siz[bel[v[i]]]++;
      }
      for (ri i=1;i<=n;i++) id[i]=i;
      sort(id+1,id+n+1,cmp);
      int ans=0,cnt=0;
      for (ri i=1;i<=n;i++) {
        int cur=id[i];
        if (siz[bel[cur]]>1) {
          siz[bel[cur]]--;
          ans+=a[cur];
          if (++cnt==k) {
            printf("%d
    ",ans);
            return 0;
          }
        }
      }
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    C# Nugut CsvHelper 使用
    C# 读写txt
    Js打开QQ聊天对话窗口
    Js 读写Cookies
    js 计算时间差
    C# 读取CSV文件
    使用 SqlBulkCopy 批量插入数据
    sql 添加列并设置默认值
    C# 获取Enum 描述和值集合
    SQL连接其它服务器操作
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11437503.html
Copyright © 2011-2022 走看看