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;
}

 

原文地址:https://www.cnblogs.com/jiachinzhao/p/4937583.html