zoukankan      html  css  js  c++  java
  • UVA 11478(差分约束 + 二分)

    题意:

    给定一个有向图,每条边都有一个权值,每次你可以选择一个结点和一个整数的,把所有以v为终点的边的权值减去d,

    把所有以v为起点的边的权值加上d

    最后要让所有边的权的最小值非负且尽量大

    代码

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int N = 1e3;
    const int inf  = 0x3f3f3f3f;
    int dist[N],inq[N],cnt[N];
    struct node
    {
        int v,w;
        node(int v,int w):v(v),w(w) {};
    };
    vector<node> G[N];
    void init(int n)
    {
        for(int i = 0; i<=n; i++) G[i].clear();
    }
    bool spfa(int n)
    {
        queue<int> q;
        q.push(0);
        memset(inq,0,sizeof(inq));
        memset(cnt,0,sizeof(cnt));
        memset(dist,inf,sizeof(dist));
        dist[0] = 0;
        inq[0] = 1;
        cnt[0] = 1;
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            inq[u] = 0;
            for(int i = 0; i<G[u].size(); i++)
            {
                int v = G[u][i].v, w= G[u][i].w;
                if(dist[v]>dist[u] + w)
                {
                    dist[v] = dist[u] + w;
                    if(!inq[v]) q.push(v),inq[v] = 1;
                    if(++cnt[v]>n) return true;
                }
            }
        }
        return false;
    }
    bool test(int mid,int n)
    {
        for(int i = 1; i<=n; i++)
            for(int j = 0; j<G[i].size(); j++)
                G[i][j].w -=mid;
        int ret = spfa(n);
        for(int i = 1; i<=n; i++)
            for(int j = 0; j<G[i].size(); j++)
                G[i][j].w +=mid;
        return ret;
    }
    int main()
    {
        int V,E;
        while(~scanf("%d%d",&V,&E))
        {
            init(V);
            int ub = 0;
            int u ,v ,w;
            for(int i = 0; i<E; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                G[u].push_back(node(v,w));
                ub = max(w,ub);
            }
            for(int i = 1; i<=V; i++)
                G[0].push_back(node(i,0));
            int L = 1, R = ub;
            if(test(L,V)) puts("No Solution");
            else if(!test(ub+1,V)) puts("Infinite");
            else
            {
                while(L<R)
                {
                    int mid = L + (R -L)/2;
                    if(test(mid,V)) R = mid ;
                    else  L = mid + 1;
                }
                printf("%d
    ",L-1);
            }
        }
        return 0;
    }
    

     

  • 相关阅读:
    设计模式 享元模式(池化技术)
    设计模式 混合模式(整体部分模式)
    设计模式 适配器模式
    Flex3示例、 安装 、注册码
    VS2010错误
    转载:glut.h 与 stdlib.h中 的exit()重定义问题的解决
    宿迁软件QQ群(109233721)
    百度地图 开发API接口啦
    Sublime Text 插件个人使用总结&推荐
    sublime text2 使用安装插件中文乱码问题解决
  • 原文地址:https://www.cnblogs.com/jiachinzhao/p/4937583.html
Copyright © 2011-2022 走看看