zoukankan      html  css  js  c++  java
  • uva 12587 二分枚举

    思路:维护一个森林,二分枚举最小的最大值。

    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pb push_back
    #define mp make_pair
    #define Maxn 20010
    #define Maxm 40010
    #define LL long long
    #define Abs(x) ((x)>0?(x):(-x))
    #define lson(x) (x<<1)
    #define rson(x) (x<<1|1)
    #define inf 1e15
    #define lowbit(x) (x&(-x))
    #define clr(x,y) memset(x,y,sizeof(x))
    #define Mod 1000000007
    using namespace std;
    int head[Maxn],vi[Maxn],dfn[Maxn],low[Maxn],num[Maxn],is[Maxn],Stack[Maxn],top,e,lab;
    int n,m;
    LL val[Maxn],need[Maxn],cnt;
    struct Edge{
        int u,v,next,f;
        LL val;
    }edge[Maxm];
    void init()
    {
        clr(head,-1);
        clr(vi,0);
        clr(is,0);
        clr(need,0);
        clr(dfn,0);
        clr(low,0);
        clr(num,0);
        e=lab=cnt=0;
    }
    void add(int u,int v,LL val)
    {
        //cout<<u<<" "<<v<<endl;
        edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].f=0,edge[e].next=head[u],head[u]=e++;
    }
    void Tarjan(int u)
    {
        int i,v,cc;
        ++cnt;
        vi[u]=1;
        dfn[u]=low[u]=++lab;
        Stack[++top]=u;
        for(i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].v;
            if(edge[i].f) continue;
            edge[i].f=edge[i^1].f=1;
            if(!dfn[v]){
                cc=cnt;
                Tarjan(v);
                if(low[v]>dfn[u]){
                    is[u]=1;
                    num[v]=cnt-cc;
                }
                low[u]=min(low[u],low[v]);
            }
            else low[u]=min(low[u],dfn[v]);
        }
    }
    bool dfs(int u,LL nal)
    {
        int i,v;
        need[u]=val[u];
        vi[u]=1;
        for(i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].v;
            if(vi[v]) continue;
            if(!dfs(v,nal))
                return false;
            if(is[u]){
                if(num[v]*(cnt-num[v])*edge[i].val+need[v]>nal)
                    need[u]+=num[v]*(cnt-num[v])*edge[i].val;
            }
            if(need[u]>nal)
                return false;
        }
        return true;
    }
    bool OK(LL x,int p)
    {
        int i,j;
        for(i=0;i<=top;i++) vi[Stack[i]]=0;
        for(i=0;i<=top;i++) if(val[Stack[i]]>x){
            return false;
        }
        if(!dfs(p,x))
            return false;
        return true;
    }
    void solve()
    {
        int i,j;
        LL ans=0;
        for(i=1;i<=n;i++) if(!dfn[i]){
            Tarjan(i);
            LL l,r,mid;
            l=0,r=inf;
            while(l<r){
                mid=(l+r)>>1;
                if(OK(mid,i))
                    r=mid;
                else
                    l=mid+1;
            }
            ans=max(l,ans);
            cnt=0;
            top=0;
        }
        printf("%lld
    ",ans);
        return ;
    }
    int main()
    {
        int i,j,u,v,t,Ca=0;
        LL cc;
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%d%d",&n,&m);
            for(i=1;i<=n;i++)
                scanf("%lld",val+i);
            for(i=1;i<=m;i++){
                scanf("%d%d%lld",&u,&v,&cc);
                add(u,v,cc);
                add(v,u,cc);
            }
            printf("Case %d: ",++Ca);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    Bugku-CTF之各种绕过
    算法竞赛入门经典 第四章 学习笔记 2
    时钟周期,CPU周期,指令周期,CPU时间片
    big-endian和little-endian
    android px,dp,sp大小转换工具
    SharedPreferences漏洞, 无法避免,所以不要在里面存储敏感信息
    java正则表达式入门
    adb命令
    android largeheap 的设定
    关于java中接口定义常量和类定义常量的区别
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3347841.html
Copyright © 2011-2022 走看看