Ural 1277 - Cops and Thieves 无向图的最小点割

来源:互联网 发布:看gv的软件 编辑:程序博客网 时间:2024/04/30 01:37

                 题意:

                          在一个无向图中小偷要偷东西..小偷从s点出发..要偷的东在点e...警察可以用一些警力封锁一些点让小偷无论如何都不能到达e....现在告诉能派出的最大警力以及封锁一个点所需要的警力..注意s,e不能封锁..问能否保证小偷无论如何都不能到达e....

                 题解:

                          很裸的最小点割了..无向图的..一样..做双边..拆点...拆点之间的容量为这个点所需的警察数量...其他边都是容量无穷大...跑最大流即为最小割...恶心的是数据里有起点=终点的..特判NO..


Program:

#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#define MAXN 505#define MAXM 50005#define oo 1000000007#define ll long longusing namespace std; struct Dinic      {             struct node           {                  int c,u,v,next;           }edge[MAXM];           int ne,head[MAXN];           int cur[MAXN], ps[MAXN], dep[MAXN];           void initial()           {                 ne=2;                 memset(head,0,sizeof(head));            }           void addedge(int u, int v,int c)           {                  edge[ne].u=u,edge[ne].v=v,edge[ne].c=c,edge[ne].next=head[u];                 head[u]=ne++;                 edge[ne].u=v,edge[ne].v=u,edge[ne].c=0,edge[ne].next=head[v];                 head[v]=ne++;           }           int MaxFlow(int s,int t)           {                                      int tr, res = 0;                 int i,j,k,f,r,top;                 while(1)                 {                        memset(dep, -1, sizeof(dep));                        for(f=dep[ps[0]=s]=0,r=1;f!= r;)                           for(i=ps[f++],j=head[i];j;j=edge[j].next)                             if(edge[j].c&&dep[k=edge[j].v]==-1)                             {                                   dep[k]=dep[i]+1;                                   ps[r++]=k;                                   if(k == t){  f=r; break;  }                             }                        if(dep[t]==-1) break;                        memcpy(cur,head,sizeof(cur));                        i=s,top=0;                        while(1)                        {                             if(i==t)                             {                                   for(tr=oo,k=0;k<top;k++)                                      if(edge[ps[k]].c<tr)                                         tr=edge[ps[f=k]].c;                                   for(k=0;k<top;k++)                                   {                                         edge[ps[k]].c-=tr;                                         edge[ps[k]^1].c+=tr;                                   }                                   i=edge[ps[top=f]].u;                                   res+= tr;                             }                             for(j=cur[i];cur[i];j=cur[i]=edge[cur[i]].next)                                  if(edge[j].c && dep[i]+1==dep[edge[j].v]) break;                              if(cur[i])  ps[top++]=cur[i],i=edge[cur[i]].v;                              else                             {                                     if(!top) break;                                     dep[i]=-1;                                     i=edge[ps[--top]].u;                             }                       }                 }                 return res;          }    }T;    int main() {                 int sum,n,m,s,e,i,x,y;       while (~scanf("%d",&sum))      {               scanf("%d%d%d%d",&n,&m,&s,&e);               s=s<<1|1,e=e<<1,T.initial();                for (i=1;i<=n;i++) scanf("%d",&x),                                  T.addedge(i<<1,i<<1|1,x),T.addedge(i<<1|1,i<<1,x);               while (m--)               {                        scanf("%d%d",&x,&y);                        T.addedge(x<<1|1,y<<1,oo),T.addedge(y<<1|1,x<<1,oo);               }                             if (T.MaxFlow(s,e)<=sum && s!=e+1) printf("YES\n");                                            else  printf("NO\n");      }      return 0;}


原创粉丝点击