zoukankan      html  css  js  c++  java
  • POI2012 BEZ-Minimalist Security | noi.ac #537 Graph

    题目链接:戳我

    首先注意这张图有可能不连通!!

    然后我们考虑对于每一个联通块,首先任意确定一个点,给它设最终值为x,然后进行搜索。(因为对于一个联通块而言,我们知道一个点的最终值,那么整个联通块上面点的值就都知道了)
    我们发现这些值只有-x+b或者x+b两种情况。
    当一个点被访问到了第二次,如果两次x的系数一样且b不一样,就可以直接输出NIE。如果系数不一样,那么也就可以确认x的大小了(之后记得还要检验一下子)。
    如果没有点被访问两次或者以上,那么就是一些不等式的限制条件,我们直接解不等式就行啦。而总数的极值一定也在x的极值上QAQ

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<ctime>
    #define MAXN 500010
    #define MAXM 3000010
    using namespace std;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
        return x*f;
    }
    int n,m,t,cnt,tot;
    int head[MAXN],p[MAXN],done[MAXN],col[MAXN],vec[MAXN];
    long long minn_ans,maxx_ans;
    struct Node{int k,b;}node[MAXN];
    struct Edge{int nxt,to,dis;}edge[MAXM<<1];
    inline void add(int from,int to,int dis)
    {
        edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis;
        head[from]=t;
    }
    inline void calc(int x,int cur_ans)
    {
        if(cur_ans)
        {
            for(int i=1;i<=tot;i++)
            {
                int now=vec[i];
                int sum=node[now].k*cur_ans+node[now].b;
                if(sum<0||sum>p[now])
                {
                    printf("NIE
    ");
                    exit(0);
                }
                else 
                {
                    minn_ans+=p[now]-sum;
                    maxx_ans+=p[now]-sum;
                }
            }
        }
        else
        {
            int l=0,r=0x3f3f3f3f;
            for(int i=1;i<=tot;i++)
            {
                int now=vec[i];
                if(node[now].k==-1) 
                {
                    l=max(l,node[now].b-p[now]);
                    r=min(r,node[now].b);
                }
                else 
                {
                    l=max(l,-node[now].b);
                    r=min(r,p[now]-node[now].b);
                }
                if(l>r)
                {
                    printf("NIE
    ");
                    exit(0);
                }
            }   
            long long cur_ans1=0,cur_ans2=0;
            for(int i=1;i<=tot;i++)
            {
                int now=vec[i];
                cur_ans1+=p[now]-node[now].k*l-node[now].b;
                cur_ans2+=p[now]-node[now].k*r-node[now].b;
            }
            minn_ans+=min(cur_ans1,cur_ans2);
            maxx_ans+=max(cur_ans1,cur_ans2);
        }
        return;
    }
    inline void paint(int x,int color)
    {
        tot=0;
        int cur_ans=0;
        queue<int>q;
        q.push(x);
        node[x]=(Node){1,0};
        while(!q.empty())
        {
            if((double)clock()/CLOCKS_PER_SEC>1.8) 
            {
                printf("NIE
    ");
                exit(0);
            }
            int u=q.front();q.pop();
            if(!col[u]) vec[++tot]=u;
            col[u]=color;
            for(int i=head[u];i;i=edge[i].nxt)
            {
                int v=edge[i].to;
                int v_k=(node[u].k==1)?-1:1;
                int v_b=edge[i].dis-node[u].b;
                if(!col[v]) 
                {
                    node[v]=(Node){v_k,v_b};
                    q.push(v);
                    continue;
                }
                if(col[v]==color)
                {
                    if(node[v].k==v_k&&node[v].b!=v_b) 
                    {
                        printf("NIE
    ");
                        exit(0);
                    }
                    if(node[v].k!=v_k)
                    {
                        int cur=(node[v].b-v_b)/(v_k-node[v].k);
                        if(cur*(v_k-node[v].k)!=(node[v].b-v_b)) 
                        {
                            printf("NIE
    ");
                            exit(0);
                        }
                        if(!cur_ans) cur_ans=cur;
                        else if(cur_ans!=cur) 
                        {
                            printf("NIE
    ");
                            exit(0);
                        } 
                    }
                }
            }
        }
        calc(x,cur_ans);
        return;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        n=read(),m=read();
        for(int i=1;i<=n;i++) p[i]=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),w=read();
            add(x,y,w),add(y,x,w);
        }
        for(int i=1;i<=n;i++)
        {
            if(!col[i])
                cnt++,paint(i,cnt);
        }
        printf("%lld %lld
    ",minn_ans,maxx_ans);
        return 0;
    }
    
  • 相关阅读:
    JS标签获取另一个页面传过来的href值
    jsp/servlet实现简单上传和下载
    servlet跳转页面后图片不显示
    Nginx 配置实例-动静分离
    将博客搬至博客园
    nginx 配置实例-反向代理
    Nginx 简介与安装、常用的命令和配置文件
    nginx 配置实例-负载均衡
    nginx 配置实例-反向代理
    Nginx 简介与安装、常用的命令和配置文件
  • 原文地址:https://www.cnblogs.com/fengxunling/p/11146402.html
Copyright © 2011-2022 走看看