• BZOJ1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害


    n<=3000个点m<=20000条无向边的图,有p<=n个出发点,每个出发点都不可拆,现拆一些点使每个出发点都不能到达点1,求最小点数。

    简单的最小割。每个点拆成两个x和y,无向边A--B即Ay->Bx,By->Ax,每个点拆成的x和y再连边容量1,然后建超级源向p个点连边,最大流,没了。

    错误。没看题。p个点不可割。WA了一发。正确做法只要把p个点的x->y的边容量设inf即可。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<math.h>
      6 //#include<iostream>
      7 using namespace std;
      8 
      9 int n,m,p;
     10 #define maxn 6011
     11 #define maxm 100011
     12 const int inf=0x3f3f3f3f;
     13 struct Network
     14 {
     15     struct Edge{int to,next,cap,flow;}edge[maxm];
     16     int first[maxn],le,n;
     17     void clear(int n)
     18     {
     19         memset(first,0,sizeof(first));
     20         le=2;this->n=n;
     21     }
     22     void in(int x,int y,int cap)
     23     {
     24         Edge &e=edge[le];
     25         e.to=y;e.cap=cap;e.flow=0;
     26         e.next=first[x];first[x]=le++;
     27     }
     28     void insert(int x,int y,int cap)
     29     {
     30         in(x,y,cap);
     31         in(y,x,0);
     32     }
     33     int s,t,que[maxn],head,tail,dis[maxn],cur[maxn];
     34     bool bfs()
     35     {
     36         memset(dis,0,sizeof(dis));
     37         dis[s]=1;
     38         que[head=(tail=1)-1]=s;
     39         while (head!=tail)
     40         {
     41             const int now=que[head++];
     42             for (int i=first[now];i;i=edge[i].next)
     43             {
     44                 Edge &e=edge[i];
     45                 if (e.cap>e.flow && !dis[e.to])
     46                 {
     47                     dis[e.to]=dis[now]+1;
     48                     que[tail++]=e.to;
     49                 }
     50             }
     51         }
     52         return dis[t];
     53     }
     54     int dfs(int x,int a)
     55     {
     56         if (x==t || !a) return a;
     57         int flow=0,f;
     58         for (int &i=cur[x];i;i=edge[i].next)
     59         {
     60             Edge &e=edge[i];
     61             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0)
     62             {
     63                 e.flow+=f;
     64                 edge[i^1].flow-=f;
     65                 flow+=f;
     66                 a-=f;
     67                 if (!a) break;
     68             }
     69         }
     70         return flow;
     71     }
     72     int Dinic(int s,int t)
     73     {
     74         this->s=s,this->t=t;
     75         int flow=0;
     76         while (bfs())
     77         {
     78             for (int i=1;i<=n;i++) cur[i]=first[i];
     79             flow+=dfs(s,0x3f3f3f3f);
     80         }
     81         return flow;
     82     }
     83 }g;
     84 int x,y;int vis[maxn];
     85 int main()
     86 {
     87     scanf("%d%d%d",&n,&m,&p);
     88     g.n=(n<<1)^1;int s=g.n,t=1;
     89     for (int i=1;i<=m;i++)
     90     {
     91         scanf("%d%d",&x,&y);
     92         g.insert(x+n,y,inf);
     93         g.insert(y+n,x,inf);
     94     }
     95     memset(vis,0,sizeof(vis));
     96     for (int i=1;i<=p;i++)
     97     {
     98         scanf("%d",&x);vis[x]=1;
     99         g.insert(s,x,inf);
    100     }
    101     for (int i=1;i<=n;i++) if (!vis[i]) g.insert(i,i+n,1);else g.insert(i,i+n,inf);
    102     printf("%d
    ",g.Dinic(s,t));
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    WINNER队成立(第二天)
    新学期组队合作
    构建之法第8、9、10章
    第一阶段冲刺(第一天)
    作业六:小学生四则运算之NABCD模型与产品Backlog。
    构建之法第六章、第七章观后感
    四则运算,测试与封装。
    使用Webpack4 搭建React项目
    算法一小时--希尔排序
    算法一小时-插入排序
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7435213.html
Copyright © 2020-2023  润新知