zoukankan      html  css  js  c++  java
  • BZOJ2095:[POI2010]Bridges(最大流,欧拉图)

    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

    注意:通过桥为欧拉回路

    Solution

    首先二分一下答案,然后问题就变成了求混合图的欧拉回路。

    这是网络流比较经典的一个问题,详细做法可以看这篇博客

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<queue>
      6 #define N (5009)
      7 using namespace std;
      8 
      9 struct Edge{int to,next,flow;}edge[N<<1];
     10 int n,m,a[N],b[N],c[N],d[N];
     11 int s,e=5000,tot,Depth[N],Deg[N];
     12 int head[N],num_edge;
     13 queue<int>q;
     14 
     15 void add(int u,int v,int l)
     16 {
     17     edge[++num_edge].to=v;
     18     edge[num_edge].next=head[u];
     19     edge[num_edge].flow=l;
     20     head[u]=num_edge;
     21 }
     22 
     23 int DFS(int x,int low)
     24 {
     25     if (x==e || !low) return low;
     26     int f=0;
     27     for (int i=head[x]; i; i=edge[i].next)
     28         if (Depth[edge[i].to]==Depth[x]+1)
     29         {
     30             int Min=DFS(edge[i].to,min(low,edge[i].flow));
     31             edge[i].flow-=Min;
     32             edge[((i-1)^1)+1].flow+=Min;
     33             f+=Min; low-=Min;
     34             if (!low) break;
     35         }
     36     if (!f) Depth[x]=-1;
     37     return f;
     38 }
     39 
     40 bool BFS(int s,int e)
     41 {
     42     memset(Depth,0,sizeof(Depth));
     43     Depth[s]=1; q.push(s);
     44     while (!q.empty())
     45     {
     46         int x=q.front(); q.pop();
     47         for (int i=head[x]; i; i=edge[i].next)
     48             if (!Depth[edge[i].to] && edge[i].flow)
     49             {
     50                 Depth[edge[i].to]=Depth[x]+1;
     51                 q.push(edge[i].to);
     52             }
     53     }
     54     return Depth[e];
     55 }
     56 
     57 int Dinic(int s,int e)
     58 {
     59     int ans=0;
     60     while (BFS(s,e)) ans+=DFS(s,0x7fffffff);
     61     return ans;
     62 }
     63 
     64 bool check(int lim)
     65 {
     66     memset(head,0,sizeof(head));
     67     num_edge=0;
     68     
     69     for (int i=1; i<=m; ++i)
     70     {
     71         if (c[i]>lim) return 0;
     72         if (d[i]<=lim) add(a[i],b[i],1), add(b[i],a[i],0);
     73     }
     74     for (int i=1; i<=n; ++i)
     75     {
     76         if (Deg[i]<0) add(s,i,-Deg[i]/2), add(i,s,0);
     77         if (Deg[i]>0) add(i,e,Deg[i]/2), add(e,i,0);
     78     }
     79     return Dinic(s,e)==tot/2;
     80 }
     81 
     82 int main()
     83 {
     84     scanf("%d%d",&n,&m);
     85     for (int i=1; i<=m; ++i)
     86     {
     87         scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
     88         if (c[i]>d[i]) swap(a[i],b[i]), swap(c[i],d[i]);
     89         Deg[a[i]]--, Deg[b[i]]++;
     90     }
     91     for (int i=1; i<=n; ++i)
     92         if (Deg[i]%2) {puts("NIE"); return 0;}
     93         else tot+=abs(Deg[i]/2);
     94     int l=1,r=1000,ans=-1;
     95     while (l<=r)
     96     {
     97         int mid=(l+r)>>1;
     98         if (check(mid)) ans=mid, r=mid-1;
     99         else l=mid+1;
    100     }
    101     printf("%d
    ",ans);
    102 }
  • 相关阅读:
    TypeScript入门( 一)
    PureComponent: setState未触发render渲染
    再次了解深浅拷贝问题
    关于wepack2.0报错问题
    ES7及ES8的新特性
    闭包
    setState是异步还是同步?
    SQL注入测试之DVWA环境
    i春秋实验--struts2远程命令执行S2-045漏洞利用与修复
    i春秋实验--IIS写权限漏洞利用
  • 原文地址:https://www.cnblogs.com/refun/p/10443314.html
Copyright © 2011-2022 走看看