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\n",g.Dinic(s,t));
103     return 0;
104 }
View Code

 

posted @ 2017-08-26 14:07  Blue233333  阅读(243)  评论(0编辑  收藏  举报