zoukankan      html  css  js  c++  java
  • LOJ-10095(缩点的特殊使用)

    题目链接:传送门

    思路:

    缩点求最值,但是有一点行不通,如果被选中的点才能缩点,否则缩点没有意义;

    所以就先缩选中的点,然后从小到大统计没有缩点的点,就是NO;

    如果找最小值,就是一个环里的最小值,然后求和就好了。

    注意:

    (1)预处理si和mon

    (2)对选中的点缩点,不然全部缩点后比较麻烦

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 500100;
    const int INF = 99999999;
    int head[maxn],next[maxn],ver[maxn],tot;
    int num[maxn],low[maxn],co[maxn],tim,col,si[maxn];
    int st[maxn],top;
    int mon[maxn],in[maxn];
    int MIN(int x,int y)
    {
        return x<y?x:y;
    }
    void Init()
    {
        for(int i=0;i<maxn;i++) si[i]=INF,mon[i]=INF;
        tot=0;col=0;tim=0;top=0;
    }
    void addedge(int u,int v)
    {
        ver[++tot]=v;next[tot]=head[u];head[u]=tot;
    }
    void Tarjan(int u)
    {
        int i,v;
        low[u]=num[u]=++tim;
        st[++top]=u;
        for(i=head[u];i;i=next[i]){
            v=ver[i];
            if(!num[v]){
                Tarjan(v);
                low[u]=MIN(low[u],low[v]);
            } 
            else if(!co[v]) low[u]=MIN(low[u],num[v]);
        }
        if(low[u]==num[u]){
            col++;
            co[u]=col;
            si[col]=mon[u];
            while(st[top]!=u){
                si[col]=MIN(si[col],mon[st[top]]);
                co[st[top]]=col;
                top--;
            }
            top--;
        }
    }
    int main(void)
    {
        int i,j,x,y,n,pp,rr;
        scanf("%d%d",&n,&pp);
        Init();
        for(i=1;i<=pp;i++){
            scanf("%d%d",&x,&y);
            mon[x]=y;
        }
        scanf("%d",&rr);
        for(i=1;i<=rr;i++){
            scanf("%d%d",&x,&y);
            addedge(x,y);
        }
        
        for(i=1;i<=n;i++)
        if(!num[i]&&mon[i]!=INF) Tarjan(i);
        
        for(i=1;i<=n;i++)
        if(!num[i]){
            printf("NO
    %d",i);
            return 0;
        }
        for(i=1;i<=n;i++){
            for(j=head[i];j;j=next[j]){
                if(co[i]!=co[ver[j]]){
                    in[co[ver[j]]]++;
                }
            }
        }
        
        int ans=0;
        for(i=1;i<=col;i++)
        if(in[i]==0) ans+=si[i];
        printf("YES
    %d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    myslq的更新丢失实例
    特价版线程池ThreadPoolExecutor实现
    通过SCP实现Linux服务器和本地Win10机器的文件上传下载
    数据库连接池的一种实现方案
    JDBC的驱动注册浅析
    Mysql数据库的JDBC查询实例
    RabbitMQ的安装
    Rabbitmq—基础
    Datatable某一列转List
    js Jquery 数据移除元素/删除元素
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10368942.html
Copyright © 2011-2022 走看看