zoukankan      html  css  js  c++  java
  • poj 3281(网络流+拆点)

    题目链接:http://poj.org/problem?id=3281

    思路:设一个超级源点和一个超级汇点,源点与食物相连,饮料与汇点相连,然后就是对牛进行拆点,一边喜欢的食物相连,一边与喜欢的饮料相连,拆分的牛之间也连边,所有边的容量均为1.然后跑最大流就可以了。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 #define MAXN 444
      8 #define MAXM 4444444
      9 #define inf 1<<30
     10 
     11 struct Edge{
     12     int v,cap,next;
     13 }edge[MAXM];
     14 
     15 int N,F,D,NE,vs,vt,NV;
     16 int head[MAXN];
     17 
     18 void Insert(int u,int v,int cap)
     19 {
     20     edge[NE].v=v;
     21     edge[NE].cap=cap;
     22     edge[NE].next=head[u];
     23     head[u]=NE++;
     24 
     25     edge[NE].v=u;
     26     edge[NE].cap=0;
     27     edge[NE].next=head[v];
     28     head[v]=NE++;
     29 }
     30 
     31 int level[MAXN],gap[MAXN];
     32 void bfs(int vt)
     33 {
     34     memset(level,-1,sizeof(level));
     35     memset(gap,0,sizeof(gap));
     36     level[vt]=0;
     37     gap[level[vt]]++;
     38     queue<int>que;
     39     que.push(vt);
     40     while(!que.empty()){
     41         int u=que.front();
     42         que.pop();
     43         for(int i=head[u];i!=-1;i=edge[i].next){
     44             int v=edge[i].v;
     45             if(level[v]<0){
     46                 level[v]=level[u]+1;
     47                 gap[level[v]]++;
     48                 que.push(v);
     49             }
     50         }
     51     }
     52 }
     53 
     54 int pre[MAXN],cur[MAXN];
     55 int SAP(int vs,int vt)
     56 {
     57     bfs(vt);
     58     memset(pre,-1,sizeof(pre));
     59     memcpy(cur,head,sizeof(head));
     60     int maxflow=0,aug=inf;
     61     int u=pre[vs]=vs;
     62     gap[0]=NV;
     63     while(level[vs]<NV){
     64         bool flag=false;
     65         for(int &i=cur[u];i!=-1;i=edge[i].next){
     66             int v=edge[i].v;
     67             if(edge[i].cap>0&&level[u]==level[v]+1){
     68                 flag=true;
     69                 pre[v]=u;
     70                 u=v;
     71                 aug=min(aug,edge[i].cap);
     72                 if(v==vt){
     73                     maxflow+=aug;
     74                     for(u=pre[v];v!=vs;v=u,u=pre[u]){
     75                         edge[cur[u]].cap-=aug;
     76                         edge[cur[u]^1].cap+=aug;
     77                     }
     78                     aug=inf;
     79                 }
     80                 break;
     81             }
     82         }
     83         if(flag)continue;
     84         int minlevel=NV;
     85         for(int i=head[u];i!=-1;i=edge[i].next){
     86             int v=edge[i].v;
     87             if(edge[i].cap>0&&level[v]<minlevel){
     88                 minlevel=level[v];
     89                 cur[u]=i;
     90             }
     91         }
     92         if(--gap[level[u]]==0)break;
     93         level[u]=minlevel+1;
     94         gap[level[u]]++;
     95         u=pre[u];
     96     }
     97     return maxflow;
     98 }
     99 
    100 
    101 int main()
    102 {
    103     int x,y,f,d,ans;
    104     while(~scanf("%d%d%d",&N,&F,&D)){
    105         NE=0;
    106         memset(head,-1,sizeof(head));
    107         vs=0,vt=F+D+N+N+1,NV=vt+1;
    108         for(int i=1;i<=F;i++)Insert(vs,i,1);
    109         for(int i=1;i<=N;i++)Insert(F+D+i,F+D+i+N,1);
    110         for(int i=1;i<=D;i++)Insert(F+i,vt,1);
    111         for(int i=1;i<=N;i++){
    112             scanf("%d%d",&f,&d);
    113             while(f--){
    114                 scanf("%d",&x);
    115                 Insert(x,F+D+i,1);
    116             }
    117             while(d--){
    118                 scanf("%d",&y);
    119                 Insert(F+D+i+N,F+y,1);
    120             }
    121         }
    122         ans=SAP(vs,vt);
    123         printf("%d
    ",ans);
    124     }
    125     return 0;
    126 }
    View Code
  • 相关阅读:
    KVM -> 热迁移_05
    KVM -> 虚拟机磁盘管理_03
    使用光盘搭建本地yum源
    KVM -> 虚拟机管理&console登录_02
    使用windows-SQLyog连接linux-mysql
    linux下登陆mysql失败
    忘记root密码时如何重设密码
    批处理程序:自动登陆服务端,并循环执行某些命令
    linux--磁盘分区
    linux--档案与目录管理
  • 原文地址:https://www.cnblogs.com/wally/p/3280486.html
Copyright © 2011-2022 走看看