zoukankan      html  css  js  c++  java
  • hdu 3666差分约束

    http://acm.hdu.edu.cn/showproblem.php?pid=3666

    题目描述:http://blog.sina.com.cn/s/blog_64675f540100l52h.html
    给你一个N*M的矩阵,给你两个数L和U(L <= U)问你是否存在这样的N+M个数字(计作A1….AN, B1…..BM),使矩阵中任意元素Xij,满足:
    L <= (Xij * Ai) / Bj <= U
    输出YES OR NO。
    解题报告:
    转换成:Xij * Ai – U * Bj <= 0 和 L*Bj – Xij * Ai <= 0
    差分约束中的xi – xj <= val, 中的xi和xj都不能够有系数。
    那么有了系数,只需去log把乘法转化成加法就好了:
    Log(Xij) + logAi – LogU – LogBj <= 0 è logAi – LogBj <= LogBj – LogXij
    另一个式子也同理,这样就转化成了标准的差分约束。
    注意:
    判断有无解(负环)的时候,如果用spfa,不能用入队次数大于N来判断,会超时。
    有如下两种比较可靠的方法(一般情况下)
    1:某个点入队次数大于sqrt(N)的时候
    2:所有入队次数大于T * (N + M),其中T一般取2

    分析:题目意思就是是否存在ai,bj,使得l<=cij*(ai/bj)<=u (1<=i<=n,1<=j<=m)成立

    首先,把cij除到两边:l'<=ai/bj<=u',如果差分约束的话,应该是ai-bj的形式,于是可以取对数

    log(l')<=log(ai)-log(bj)<=log(u')

    把log(ai)和log(bj)看成两个点ai和bj,化成求最短路的形式:dis[ai]-dis[bj]<=log(u'),dis[bj]-dis[ai]<=-log(l')

    转化为差分约束后,spfa拿下
    http://blog.csdn.net/cscj2010/article/details/7759630

    View Code
    // I'm lanjiangzhou
    //C
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <math.h>
    #include <time.h>
    //C++
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <cctype>
    #include <stack>
    #include <string>
    #include <list>
    #include <queue>
    #include <map>
    #include <vector>
    #include <deque>
    #include <set>
    using namespace std;
    
    //*************************OUTPUT*************************
    #ifdef WIN32
    #define INT64 "%I64d"
    #define UINT64 "%I64u"
    #else
    #define INT64 "%lld"
    #define UINT64 "%llu"
    #endif
    
    //**************************CONSTANT***********************
    #define INF 0x3f3f3f3f
    
    // aply for the memory of the stack
    //#pragma comment (linker, "/STACK:1024000000,1024000000")
    //end
    const int maxn =1010;
    int head[maxn];
    int vis[maxn];
    int _count[maxn];//用来记录同一个点入队列的次数
    int n,m,cnt;
    
    struct point{
        int v,next;//终点,指向下一条边
        double w;//权值
    }edge[maxn*maxn];
    
    double dis[maxn];
    
    void CreateMap(int u,int v,double w){
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    int spfa(){
        memset(vis,0,sizeof(vis));
        memset(_count,0,sizeof(_count));
        for(int i=1;i<=n+m;i++){
            dis[i]=INF;
        }
        dis[1]=0;
        vis[1]=1;
        _count[1]++;
        queue<int> Q;
        Q.push(1);
        while(!Q.empty()){
            int tmp=Q.front();
            Q.pop();
            vis[tmp]=0;
            for(int i=head[tmp];i!=-1;i=edge[i].next){
                if(dis[tmp]+edge[i].w<dis[edge[i].v]){
                    dis[edge[i].v]=dis[tmp]+edge[i].w;
                    if(!vis[edge[i].v]){
                        Q.push(edge[i].v);
                        vis[edge[i].v]=1;
                        if(++_count[edge[i].v]>(int)sqrt(1.0*(n+m)))
                            return 0;
                    }
                }
            }
        }
        return 1;
    }
    
    int main(){
        //int temp;
        double l,u;
        while(scanf("%d%d%lf%lf",&n,&m,&l,&u)!=EOF){
            memset(head,-1,sizeof(head));
            cnt=1;
            int temp;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    scanf("%d",&temp);
                    CreateMap(i,j+n,-log(l*1.0/temp));
                    CreateMap(j+n,i,log(u*1.0/temp));
                }
            }
            int flag=spfa();
            if(flag) printf("YES\n");
            else printf("NO\n");
        }
        return 0;
    }

     http://acm.hust.edu.cn/vjudge/contest/view.action?cid=21609#overview

  • 相关阅读:
    第四次作业——个人作业——软件案例分析
    作业五——团队项目——需求规格说明书
    团队项目——团队展示
    作业三——结对编程
    作业二——结对项目之需求分析与原型模型设计
    leetcode 212 单词搜索II
    leetcode 130. 被围绕的区域
    leetcode 695 Max Area of Island 岛的最大面积
    【《算法》学习笔记】一:
    leetcode 191 位1的个数
  • 原文地址:https://www.cnblogs.com/lanjiangzhou/p/3006185.html
Copyright © 2011-2022 走看看