zoj-3792-Romantic Value-最小割+数值转化

如果不需要求边的个数的话,就是一个裸的最小割问题。

求边的个数就用边的权值记录一下。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include<queue>
using namespace std;
#define INF 99999999
#define LL long long
const LL maxn =55;
const LL maxm =4400;
const LL oo = (LL)1<<37;
struct Arclist
{
    LL cnt, head[maxn], dis[maxn];
    LL cur[maxn], pre[maxn], gap[maxn], aug[maxn];
    struct node
    {
        LL u, v, w, next;
    }edge[maxm];
    void init()
    {
        cnt = 0;
        memset(head,-1,sizeof(head));
    }
    void add(LL u, LL v, LL w)
    {
       // cout<<u<<" "<<v<<" "<<w<<endl;
        edge[cnt].u = u;
        edge[cnt].v = v;
        edge[cnt].w = w;
        edge[cnt].next = head[u];
        head[u] = cnt++;
        edge[cnt].u = v;
        edge[cnt].v = u;
        edge[cnt].w = 0;
        edge[cnt].next = head[v];
        head[v] = cnt++;
    }
    LL sap(LL s, LL e, LL n)
    {
        LL max_flow = 0, u = s;
        LL mindis;
        for(LL i = 0; i <= n; i++)
        {
            cur[i] = head[i];
            dis[i] = 0;
            gap[i] = 0;
        }
        aug[s] = oo;
        pre[s] = -1;
        gap[0] = n;
        while(dis[s]<n)
        {
            bool flag = false;
            if(u==e)
            {
                max_flow += aug[e];
                for(LL v = pre[e]; v != -1; v = pre[v])
                {
                    LL id = cur[v];
                    edge[id].w -= aug[e];
                    edge[id^1].w += aug[e];
                    aug[v] -= aug[e];
                    if(edge[id].w==0) u = v;
                }
            }
            for(LL id = cur[u]; id != -1; id = edge[id].next)
            {
                LL v = edge[id].v;
                if(edge[id].w>0 && dis[u]==dis[v]+1)
                {
                    flag = true;
                    pre[v] = u;
                    cur[u] = id;
                    aug[v] = std::min(aug[u], edge[id].w);
                    u = v;
                    break;
                }
            }
            if(flag==false)
            {
                if(--gap[dis[u]]==0) break;
                mindis = n;
                cur[u] = head[u];
                for(LL id = head[u]; id != -1; id = edge[id].next)
                {
                    LL v = edge[id].v;
                    if(edge[id].w>0 && dis[v]<mindis)
                    {
                        mindis = dis[v];
                        cur[u] = id;
                    }
                }
                dis[u] = mindis+1;
                ++gap[dis[u]];
                if(u!=s) u = pre[u];
            }
        }
        return max_flow;
    }
}G;
int main()
{
    LL m,n,u,v,w,T,st,ed;
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld%lld%lld%lld",&n,&m,&st,&ed);
        G.init();
        LL all=0;
        while(m--)
        {
            scanf("%lld%lld%lld",&u,&v,&w);
            G.add(v,u,w*1000+1);
            G.add(u,v,w*1000+1);
            all+=w;
        }
        LL w=G.sap(st,ed,n);
       // cout<<w<<endl;
        if(w==0)cout<<"Inf"<<endl;
        else
        {
            double x,y;
            if(w%1000==0)
            {
                y=1000;
                w=w-1000;
            }
            else y=w%1000;
            x=all-w/1000;
            printf("%.2f\n",1.0*x/y);
        }
    }
    return 0;
}

zoj-3792-Romantic Value-最小割+数值转化,布布扣,bubuko.com

时间: 2024-08-03 16:40:46

zoj-3792-Romantic Value-最小割+数值转化的相关文章

ZOJ 3792 Romantic Value 最小割+求割边的数量

点击打开链接 Romantic Value Time Limit: 2 Seconds      Memory Limit: 65536 KB Farmer John is a diligent man. He spent a lot of time building roads between his farms. From his point of view, every road is romantic because the scenery along it is very harmon

ZOJ 3792 Romantic Value 最小割(最小费用下最小边数)

求最小割及最小花费 把边权c = c*10000+1 然后跑一个最小割,则flow / 10000就是费用 flow%10000就是边数. 且是边数最少的情况.. #include<stdio.h> #include<string.h> #include<iostream> #include<math.h> #include<algorithm> #include<queue> #include<vector> using

zoj 3792 Romantic Value(最小割下边数最小)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5300 大致题意:给出一个无向图,以及起点与终点.要删除一些边使得起点与终点不连通,在删掉边的权值之和最小的情况下要求删除的边数尽量少.求出一个比值:剩余边数权值和/删除的边数. 思路:删除边的权值之和最小显然是求最小割即最大流.但同时要求删除边数最少,解决方法是把边数也加到权值上去,一起求最大流,因为边数最多是1000,即每条边的边权置为 w*10000+1,1代表这一条边.

ZOJ 3792 Romantic Value(ISAP &amp;&amp; 最小割)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3792 这题是求最小割,但是不会求最小割,龙哥教的权值先*10000+1,利用前向星加边,来储存地图,得到的最大流量/10000,对%10000就是割边   Result Accepted ID  3792 Language  C++ Time  0ms 352KB #include <iostream> #include <cstdlib> #in

ZOJ 3792 Romantic Value(网络流之最小割)(找割边)

题目地址:ZOJ 3792 最小割做的太少..这题很明显是找割边.找割边就是判断正向弧是否是0.如果跑完一次最小割后正向弧流量为0的话,那就说明这个边为一条割边.但是找到了割边后再怎么办呢..中午睡觉的时候突然来了灵感..再利用这些割边求一次最大流不就行了..把割边的流量都设为1,其他的都为正无穷.那最后的流量就是最少需要的割边了.然后计算就可以了. 这次又把上限值直接设为sink+1了...导致WA了12发.....sad...以后得注意... 代码如下: #include <iostream

zoj 2676 Network Wars(最小割,01分数规划)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2676 大致题意:给出一个带权无向图,每条边有一个边权wi,求将S和T分开的一个割边集C,使得该割边集的平均边权最小,即最小化∑wi / |C| . 详见amber关于最小割模型的论文 思路:amber论文中详细讲解了如何转化成函数及建图,值得注意的是当边被重新赋权后,对于wi < 0 的边权,该边必然在最小割中,不必再建边,直接加入最大流中即可,因为求最小割时边权都为正值

tyvj P1209 - 拦截导弹 平面图最小割&amp;&amp;模型转化

P1209 - 拦截导弹 From admin    Normal (OI)总时限:6s    内存限制:128MB    代码长度限制:64KB 背景 Background 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 Description 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试验阶段,所以只有

zoj 2676 Network Wars 最小割+0-1分数规划

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2676 题意: 给出N个点和M条边,要求一个割集,使得集合中 ans = 所有边点权值和/边的数量 最小. 思路: 0-1分数规划. 具体证明参考 胡伯涛 <最小割模型在信息学竞赛中的应用> 设g = min(Σwi/Σ1) 转化为 求g使得 (Σwi - g*Σ1) = 0. 所以二分求g的值. 每次建图的时候,以1为源点,N为汇点. 原来图中每条边的容量

zoj 2587 Unique Attack 最小割判定

题目链接 让你判断最小割是否唯一. 判断方法是, 先求一遍最大流, 然后从源点dfs一次, 搜索未饱和边的数目. 从汇点dfs一次, 同样也是搜索未饱和边的数目, 看总和是否等于n. 如果等于n那么唯一. 具体可以看这里, http://www.cnblogs.com/Lyush/archive/2013/05/01/3053640.html. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a) memset(a,