【BZOJ2095】【POI2010】Bridge 网络流

题目大意

?  给你一个无向图,每条边的两个方向的边权可能不同。要求找出一条欧拉回路使得路径上的边权的最大值最小。无解输出"NIE"。

  \(2\leq n\leq 1000,1\leq m\leq 2000\)

题解

?  我们先二分答案\(ans\),把边权大于\(ans\)的边删掉。

?  现在图中还剩下一些有向边和一些无向边,也就是说这是一个混合图。

?  混合图的欧拉回路怎么求?

?  先把无向边定向(方向任意),求出每个点的出度\(d1_i\)和入度\(d2_i\)。如果存在点\(i\)使得\(|d1_i-d2_i|\)为奇数,则无解。因为你怎么反向都不可能把\(d1_i-d2_i\)变成\(0\)。

?  然后把无向边按定向的反方向在图中连边,容量为\(1\)。对于一个点\(i\),如果\(d1_i>d2_i\),则连边\(i\text{->}T\),容量为\(\frac{d1_i-d2_i}{2}\),否则连边\(S\text{->}i\),容量为\(\frac{d2_i-d1_i}{2}\)。

?  最后跑一次最大流。如果满流就有解,否则无解。

  还要用并查集判一下是不是连通图。

?  为什么这是对的?每流过一条边就表示把这条边反向。对这个网络求最大流就是调整尽可能多的边。流量平衡就表示一个点的入度和出度相同。

?  这个图把边定向得到

?  

?  建图后跑最大流可以得到

  

?  把满流边反向后得到

  

?  这就是一个欧拉回路了

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
struct list
{
    int v[100010];
    int w[100010];
    int t[100010];
    int h[1010];
    int n;
    void clear()
    {
        memset(h,0,sizeof h);
        n=0;
    }
    void add(int x,int y,int z)
    {
        n++;
        v[n]=y;
        w[n]=z;
        t[n]=h[x];
        h[x]=n;
    }
};
list l;
void add(int x,int y,int z)
{
    l.add(x,y,z);
    l.add(y,x,0);
}
int d[1010];
int S,T;
int bfs()
{
    memset(d,-1,sizeof d);
    queue<int> q;
    q.push(S);
    d[S]=0;
    int x,i;
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        for(i=l.h[x];i;i=l.t[i])
            if(l.w[i]&&d[l.v[i]]==-1)
            {
                d[l.v[i]]=d[x]+1;
                if(l.v[i]==T)
                    return 1;
                q.push(l.v[i]);
            }
    }
    return 0;
}
int op(int x)
{
    return ((x-1)^1)+1;
}
int dfs(int x,int flow)
{
    if(x==T)
        return flow;
    int c,s=0,i;
    for(i=l.h[x];i;i=l.t[i])
        if(l.w[i]&&d[l.v[i]]==d[x]+1)
        {
            c=dfs(l.v[i],min(flow,l.w[i]));
            s+=c;
            flow-=c;
            l.w[i]-=c;
            l.w[op(i)]+=c;
            if(!flow)
                break;
        }
    return s;
}
int f[1010];
int find(int x)
{
    return f[x]==x?x:f[x]=find(f[x]);
}
int lx[2010],ly[2010],w1[2010],w2[2010];
int d1[2010],d2[2010];
int c[2010];//方向
int n,m;
int abs(int x)
{
    return x>0?x:-x;
}
int check(int p)
{
    memset(d1,0,sizeof d1);
    memset(d2,0,sizeof d2);
    int i;
    for(i=1;i<=n;i++)
        f[i]=i;
    for(i=1;i<=m;i++)
    {
        if(p<w1[i]&&p<w2[i])
            return 0;
        if(p>=w1[i])
        {
            c[i]=0;
            d1[lx[i]]++;
            d2[ly[i]]++;
            f[find(lx[i])]=find(ly[i]);
        }
        else
        {
            c[i]=1;
            d1[ly[i]]++;
            d2[lx[i]]++;
            f[find(lx[i])]=find(ly[i]);
        }
    }
    for(i=1;i<=n;i++)
    {
        if(abs(d1[i]-d2[i])&1)
            return 0;
        if(i>1&&find(i)!=find(i-1))
            return 0;
    }
    l.clear();
    S=n+1;
    T=n+2;
    for(i=1;i<=m;i++)
        if(p>=w1[i]&&p>=w2[i])
            add(ly[i],lx[i],1);
//      else
//          add(lx[i],ly[i],1);
    int s=0,ans=0;
    for(i=1;i<=n;i++)
        if(d1[i]>d2[i])
        {
            add(i,T,(d1[i]-d2[i])/2);
            s+=(d1[i]-d2[i])/2;
        }
        else if(d1[i]<d2[i])
            add(S,i,(d2[i]-d1[i])/2);
    while(bfs())
        ans+=dfs(S,0x7fffffff);
    return ans==s;
}
int main()
{
//  freopen("bzoj2095.in","r",stdin);
    scanf("%d%d",&n,&m);
    int i;
    for(i=1;i<=m;i++)
        scanf("%d%d%d%d",&lx[i],&ly[i],&w1[i],&w2[i]);
    int l=1,r=1001;
    int mid;
    while(l<r)
    {
        mid=(l+r)>>1;
        if(check(mid))
            r=mid;
        else
            l=mid+1;
    }
    if(l>1000)
        printf("NIE\n");
    else
        printf("%d\n",l);
    return 0;
}

原文地址:https://www.cnblogs.com/ywwyww/p/8510609.html

时间: 2024-10-09 07:39:16

【BZOJ2095】【POI2010】Bridge 网络流的相关文章

BZOJ2095 [Poi2010]Bridges

首先二分答案...然后这张图变成了有一些有向边,有一些无向边 然后就是混合图欧拉回路的判断 我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度 对于混合图...先不管有向边,把无向边随意定向 首先要满足条件就是当前图的点的度数都是偶数,因为把一条边反向端点的出度入度之差改变了2,奇偶性不变 我们只要判断是否把部分已经定向的无向边反向以后可以满足度都是偶数这个条件 用网络流来判断 对于每条边,如果定向为$x$到$y$,则$y$向$x$连边,流量为1 对于每个点$x$,如果出度 -

bzoj2095: [Poi2010]Bridges(二分+混合图求欧拉回路)

传送门 这篇题解讲的真吼->这里 首先我们可以二分一个答案,然后把所有权值小于这个答案的都加入图中 那么问题就转化为一张混合图(既有有向边又有无向边)中是否存在欧拉回路 首先 无向图存在欧拉回路,当且仅当图的所有顶点度数都为偶数且图连通.        有向图存在欧拉回路,当且仅当图的所有顶点入度等于出度且图连通. 那么我们怎么判断混合图的欧拉回路是否存在呢? 我们把无向边的边随便定向,然后计算每一个点的入度和出度.如果有某一个点的入度和出度之差是奇数,那么肯定不存在欧拉回路. 因为欧拉回路要求

-----------------------【有趣の题目】-----------------------

做过的,有意义多次看的,有趣的题目整合包 图论相关: [BZOJ-3308]九月的咖啡店   线性筛素数+有趣的处理+最大费用最大流 [BZOJ-4205]卡牌配对   线性筛素数+最大流+玄学的效率 [BZOJ-2095]Bridge   混合图欧拉回路 [BZOJ-1797]Mincut 最小割    最大流+Tarjan+缩点+分类讨论 [BZOJ-2879]美食节    最小费用最大流+拆点+动态建图 [BZOJ-1061]志愿者招募   线性规划转最小费用最大流 [BZOJ-2118]

【BZOJ2095】[Poi2010]Bridges 动态加边网络流

[BZOJ2095][Poi2010]Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1出发,骑过每一座桥,到达每一个小岛,然后回到小岛1.霸中同学为了让YYD减肥成功,召唤了大风,由于是海上,风变得十分大,经过每一座桥都有不可避免的风阻碍YYD,YYD十分ddt,于是用泡芙贿赂了你,希望你能帮他找出一条承受的最大风力最小的路线.

算法复习——欧拉回路混合图(bzoj2095二分+网络流)

题目: Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1出发,骑过每一座桥,到达每一个小岛,然后回到小岛1.霸中同学为了让YYD减肥成功,召唤了大风,由于是海上,风变得十分大,经过每一座桥都有不可避免的风阻碍YYD,YYD十分ddt,于是用泡芙贿赂了你,希望你能帮他找出一条承受的最大风力最小的路线. Input 输入:第一行为两个用空格隔开的整数

BZOJ 2095 Poi2010 Bridges 二分答案+网络流

题目大意:给定一张图,每条边的两个方向有两个不同的权值,现在要求从1号节点出发遍历每条边一次且仅一次,最后回到1号节点,求最大边权的最小值 谁TM翻译的这道题给我滚出来看我不打死你 二分最大边的权值,然后就是经典的判断混合图欧拉回路存在性的问题了 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 2020 #define S 0 #d

HDU 2435 There is a war (网络流-最小割)

There is a war Problem Description There is a sea. There are N islands in the sea. There are some directional bridges connecting these islands. There is a country called Country One located in Island 1. There is another country called Country Another

[NetworkFlow]网络流建模相关

流 网络流问题本质上是线性规划问题的应用之一,线性规划问题的标准形式是给出一组等式约束和不等式约束,要求最优化一个线性函数. 在流问题中,变量以流量的形式出现在问题中,我们给出一个流网络(以有向图的形式)来解决有关流的问题. 流是整个网络流问题的核心所在,它实际上是定义在流网络上的一个线性函数,在流网络中,每条边都有一个流量f(u,v),流f=∑v∈Vf(S,v) 流量f(u,v)是流问题中的变量,它有两个约束,一个是不等式,一个是等式 (1)容量限制:f(u,v)≤c(u,v) (2)流量平衡

HDU 4309 Seikimatsu Occult Tonneru(网络流-最大流)

Seikimatsu Occult Tonneru Problem Description During the world war, to avoid the upcoming Carpet-bombing from The Third Reich, people in Heaven Empire went to Great Tunnels for sheltering. There are N cities in Heaven Empire, where people live, with