zoukankan      html  css  js  c++  java
  • bzoj2095: [Poi2010]Bridges

    2095: [Poi2010]Bridges

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 784  Solved: 268
    [Submit][Status][Discuss]

    Description

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

    Input

    输入:第一行为两个用空格隔开的整数n(2<=n<=1000),m(1<=m<=2000),接下来读入m行由空格隔开的4个整数a,b(1<=a,b<=n,a<>b),c,d(1<=c,d<=1000),表示第i+1行第i座桥连接小岛a和b,从a到b承受的风力为c,从b到a承受的风力为d。

    Output

    输出:如果无法完成减肥计划,则输出NIE,否则第一行输出承受风力的最大值(要使它最小)

    Sample Input

    4 4
    1 2 2 4
    2 3 3 4
    3 4 4 4
    4 1 5 4

    Sample Output

    4

    HINT

    注意:通过桥为欧拉回路

     
     
    转自 http://www.cnblogs.com/zyfzyf/p/4190255.html
    ---------------------------------------------------------------

    二分答案之后就是混合图(有向边+无向边)的欧拉回路问题。

    如何判断欧拉回路是否存在?

    把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度
    之差为奇数,那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,
    也就是总度数为偶数,存在奇数度点必不能有欧拉回路。
    好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以 2,得 x。
    也就是说,对于每一个点,只要将 x 条边改变方向(入>出就是变入,出>入就是9
    变出),就能保证出=入。如果每个点都是出=入,那么很明显,该图就存在欧拉
    回路。
    现在的问题就变成了:我该改变哪些边,可以让每个点出=入?构造网络流
    模型。首先,有向边是不能改变方向的,要之无用,删。一开始不是把无向边定
    向了吗?定的是什么向,就把网络构建成什么样,边长容量上限 1。另新建 s 和
    t。对于入>出的点 u,连接边(u, t)、容量为 x,对于出>入的点 v,连接边(s, v),
    容量为 x(注意对不同的点 x 不同)。之后,察看是否有满流的分配。有就是能
    有欧拉回路,没有就是没有。欧拉回路是哪个?察看流值分配,将所有流量非 0
    (上限是 1,流值不是 0 就是 1)的边反向,就能得到每点入度=出度的欧拉图。
    由于是满流,所以每个入>出的点,都有 x 条边进来,将这些进来的边反向,
    OK,入=出了。对于出>入的点亦然。那么,没和 s、t 连接的点怎么办?和 s 连
    接的条件是出>入,和 t 连接的条件是入>出,那么这个既没和 s 也没和 t 连接的
    点,自然早在开始就已经满足入=出了。那么在网络流过程中,这些点属于“中
    间点”。我们知道中间点流量不允许有累积的,这样,进去多少就出来多少,反
    向之后,自然仍保持平衡。

    ---------------------------------------------------------------
     1 #include<bits/stdc++.h>
     2 #define rep(i,l,r) for(int i=l;i<=r;++i)
     3 using namespace std;
     4 const int N=100000,inf=2147483647;
     5 int n,m,T,head[N],tot,l=1e8,r,mid,a[N],b[N],c[N],d[N],dis[N],ans,in[N],out[N];
     6 struct zs{
     7     int to,next,w;
     8 }e[N];
     9 inline bool bfs(){
    10      for(int i=0;i<=T;i++) dis[i]=-1; queue<int>q; q.push(0); dis[0]=0;
    11      while(!q.empty()) {
    12           int x=q.front(); q.pop();
    13           for(int k=head[x];k;k=e[k].next) 
    14              if(dis[e[k].to]<0 && e[k].w>0) {
    15                    dis[e[k].to]=dis[x]+1; q.push(e[k].to);
    16              }
    17      }
    18      if(dis[T]>0) return 1;else return 0;
    19 }
    20 int find(int x,int low){
    21      if(x==T) return low;
    22      int delta=low,now;
    23      for(int k=head[x];k;k=e[k].next) 
    24        if(e[k].w>0 && dis[e[k].to]==dis[x]+1){ 
    25            now=find(e[k].to,min(e[k].w,delta));
    26            e[k].w-=now; e[k^1].w+=now;   delta-=now;
    27            if(!delta) return low;
    28         } 
    29      dis[x]=-1;
    30      return low-delta;
    31 }
    32 inline void ins(int u,int v,int w){
    33     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w;
    34 }
    35 inline void insert(int u,int v,int w){
    36     ins(u,v,w);ins(v,u,0);
    37 }
    38 inline bool pd(int x){
    39     memset(head,0,sizeof head); tot=1;
    40     memset(in,0,sizeof in);memset(out,0,sizeof out);
    41     int sum=0,cnt=0;
    42     rep(i,1,m) {
    43         if(c[i]<=x)++out[a[i]],++in[b[i]];
    44         if(d[i]<=x)insert(b[i],a[i],1);
    45     }
    46     rep(i,1,n) if(1&abs(in[i]-out[i]))return 0;else{
    47         if(in[i]>out[i]) insert(0,i,(in[i]-out[i])/2),sum+=(in[i]-out[i])/2;
    48         else if(in[i]<out[i])insert(i,T,(out[i]-in[i])/2);
    49     }
    50     while(bfs())cnt+=find(0,inf);
    51     return cnt==sum;
    52 }
    53 int main(){
    54     scanf("%d%d",&n,&m);
    55     rep(i,1,m)scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]),r=max(r,max(c[i],d[i])),l=min(l,min(c[i],d[i]));
    56     rep(i,1,m) if(c[i]>d[i]) swap(a[i],b[i]),swap(c[i],d[i]);
    57     T=n+1;
    58     while(l<=r){
    59         mid=l+r>>1;
    60         if(pd(mid)) r=mid-1;else l=mid+1; 
    61     }
    62     if(!pd(l))puts("NIE");else printf("%d
    ",l);
    63 }
    View Code
  • 相关阅读:
    Codeforces 1491 D. Zookeeper and The Infinite Zoo (二进制处理)
    Codeforces 1479A. Searching Local Minimum(注意输入+二分)
    Codeforces 1480B. The Great Hero(阅读模拟题,注意数据范围和攻击顺序)
    Codeforces 1480A. Yet Another String Game (阅读理解题)
    windows 10 开启全盘瞬间索引功能
    JetBrains CLion C++ IDE连接wsl2(Ubuntu)时,报错"Unable to establish SSL connection"解决方案
    WorkFlowy 的 MarkDown 预览方案解决
    git 学习 完全学懂
    jeecgboot <j-popup
    面试之类加载器
  • 原文地址:https://www.cnblogs.com/Bloodline/p/6001563.html
Copyright © 2011-2022 走看看