• UVA-11478 Halum (差分约束系统)


    题目大意:一张n个节点的有向带边权图,每次操作能任选一个节点v个一个整数d,使以v为终点的边权值都减少d,以v为起点的边权值都增加d,求若干次操作后的最小边权值的非负最大值。

    题目分析:用sum[i]表示作用在节点i上的所有d之和,则对于边a->b,操作若干次后的权值为w(a,b)+sum[a]-sum[b],假设最小边权值的最大值为x,则有sum[b]-sum[a]≤w(a,b)-x。这样的所有m条边构成一个差分约束系统。二分枚举x,求解即可。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int INF=1<<30;
    struct Edge
    {
        int to,nxt,w;
    };
    Edge e[3500];
    int cnt,n,head[3000],inq[505],vis[505],dist[505];
    
    void add(int u,int v,int w)
    {
        e[cnt].to=v;
        e[cnt].w=w;
        e[cnt].nxt=head[u];
        head[u]=cnt++;
    }
    
    bool bellman_ford(int M)
    {
        queue<int>q;
        for(int i=1;i<=n;++i){
            vis[i]=inq[i]=1;
            dist[i]=0;
            q.push(i);
        }
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            inq[u]=0;
            for(int i=head[u];i!=-1;i=e[i].nxt){
                int v=e[i].to;
                if(dist[v]>dist[u]+e[i].w-M){
                    dist[v]=dist[u]+e[i].w-M;
                    if(!inq[v]){
                        inq[v]=1;
                        q.push(v);
                        if(++vis[v]>n-1)
                            return true;
                    }
                }
            }
        }
        return false;
    }
    
    int main()
    {
        int m,a,b,c;
        while(~scanf("%d%d",&n,&m))
        {
            cnt=0;
            memset(head,-1,sizeof(head));
            int maxn=0;
            while(m--)
            {
                scanf("%d%d%d",&a,&b,&c);
                add(a,b,c);
                maxn=max(maxn,c);
            }
            if(bellman_ford(1))
                printf("No Solution
    ");
            else if(!bellman_ford(maxn+1))
                printf("Infinite
    ");
            else{
                int l=1,r=maxn;
                while(l<r){
                    int x=l+(r-l+1)/2;
                    if(bellman_ford(x))
                        r=x-1;
                    else
                        l=x;
                }
                printf("%d
    ",l);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    二分法查找递归方式()
    JDBC操作MySQL(crud)
    (转)JAVA中的权限修饰符
    抽象类和接口(面试题总结)
    java基础-集合
    Java泛型通配符以及限定
    div中嵌套的多个div使用了浮动后居中的办法
    将博客搬至CSDN
    (补)Java解析XML之dom4j
    Java单元测试
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4909135.html
Copyright © 2020-2023  润新知