zoukankan      html  css  js  c++  java
  • POJ 2444 The Accomodation of Students 黑白染色+二分匹配 簡單題

    有n個人,編號為1~n,其中有m對朋友,現在給出m對朋友,問能不能把這n個人分成2個組,使得每一個組裡面的人都是互相不認識的?

    若不可以,輸出No

    若可以,問現在將認識的人兩兩配對,輸出最多可以有多少對

    說白了,這道題就是首先要判斷是不是二分圖,不是的話輸出No,是的話輸出最大匹配

    判斷二分圖:用黑白染色法,注意,整個關係圖有可能是不連通的,所以要遍歷所有的點

    這裡求最大匹配不是用匈牙利算法,而是直接轉化為最大流

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 using namespace std;
      5 
      6 const int maxn=210;
      7 const int inf=0x3f3f3f3f;
      8 
      9 inline int min(int a,int b)
     10 {
     11     return a<b?a:b;
     12 }
     13 
     14 bool link[maxn][maxn];
     15 struct Edge
     16 {
     17     int to,next;
     18 };
     19 Edge edge[maxn*maxn*2];
     20 int head[maxn];
     21 int tot;
     22 bool flag;
     23 int dye[maxn];
     24 int level[maxn];
     25 int iter[maxn];
     26 const int s=0;
     27 int t;
     28 
     29 void addedge(int u,int v)
     30 {
     31     edge[tot].to=v;
     32     edge[tot].next=head[u];
     33     head[u]=tot++;
     34 }
     35 
     36 void init(int n)
     37 {
     38     memset(link,false,sizeof link);
     39     memset(head,-1,sizeof head);
     40     memset(dye,-1,sizeof dye);
     41     tot=0;
     42     flag=true;
     43 }
     44 
     45 void to_dye(int pre ,int u)
     46 {
     47     if(pre==-1)
     48         dye[u]=1;
     49     else
     50         dye[u]=!dye[pre];
     51 
     52     for(int i=head[u];~i;i=edge[i].next)
     53     {
     54         int v=edge[i].to;
     55         if(v==pre)
     56             continue;
     57         if(dye[v]!=-1)
     58         {
     59             if(dye[v]!=dye[u])
     60                 continue;
     61             else
     62             {
     63                 flag=false;
     64             }
     65         }
     66         else
     67          to_dye(u,v);
     68     }
     69 }
     70 
     71 struct Flow_Edge
     72 {
     73     int to,cap,rev;
     74 };
     75 vector<Flow_Edge>flow_edge[maxn];
     76 
     77 void add(int from,int to,int cost)
     78 {
     79     flow_edge[from].push_back((Flow_Edge){to,cost,flow_edge[to].size()});
     80     flow_edge[to].push_back((Flow_Edge){from,0,flow_edge[from].size()-1});
     81 }
     82 
     83 void build_graph(int n)
     84 {
     85     for(int i=0;i<=n;i++)
     86         flow_edge[i].clear();
     87 
     88     t=n+1;
     89     for(int i=1;i<=n;i++)
     90     {
     91         if(dye[i]==1)
     92             add(s,i,1);
     93         else
     94             add(i,t,1);
     95     }
     96     for(int i=1;i<=n;i++)
     97     {
     98         for(int j=1;j<=n;j++)
     99         {
    100             if(i==j)
    101                 continue;
    102             if(link[i][j]||link[j][i])
    103             {
    104                 if(dye[i]==1)
    105                     add(i,j,1);
    106                 else
    107                     add(j,i,1);
    108                 link[i][j]=false;
    109                 link[j][i]=false;
    110             }
    111         }
    112     }
    113 }
    114 
    115 void bfs()
    116 {
    117     memset(level,-1,sizeof level);
    118     queue<int>que;
    119     while(!que.empty())
    120         que.pop();
    121     level[s]=1;
    122     que.push(s);
    123     while(!que.empty())
    124     {
    125         int u=que.front();
    126         que.pop();
    127         for(int i=0;i<flow_edge[u].size();i++)
    128         {
    129             Flow_Edge &e=flow_edge[u][i];
    130             if(e.cap>0&&level[e.to]<0)
    131             {
    132                 level[e.to]=level[u]+1;
    133                 que.push(e.to);
    134             }
    135         }
    136     }
    137 }
    138 
    139 int dfs(int u,int f)
    140 {
    141     if(u==t)
    142         return f;
    143     for(int &i=iter[u];i<flow_edge[u].size();i++)
    144     {
    145         Flow_Edge &e=flow_edge[u][i];
    146         if(e.cap>0&&level[e.to]>level[u])
    147         {
    148             int d=dfs(e.to,min(e.cap,f));
    149             if(d>0)
    150             {
    151                 e.cap-=d;
    152                 flow_edge[e.to][e.rev].cap+=d;
    153                 return d;
    154             }
    155         }
    156     }
    157     return 0;
    158 }
    159 
    160 int max_flow(int n)
    161 {
    162     int flow=0;
    163     while(1)
    164     {
    165         bfs();
    166         if(level[t]==-1)
    167             return flow;
    168         memset(iter,0,sizeof iter);
    169         int f;
    170         while(f=dfs(s,inf))
    171         {
    172             if(f>0)
    173                 flow+=f;
    174         }
    175     }
    176 }
    177 
    178 int main()
    179 {
    180     int n,m;
    181     while(~scanf("%d%d",&n,&m))
    182     {
    183         init(n);
    184 
    185         for(int i=0;i<m;i++)
    186         {
    187             int u,v;
    188             scanf("%d%d",&u,&v);
    189             link[u][v]=link[v][u]=true;
    190             addedge(u,v);
    191             addedge(v,u);
    192         }
    193 
    194         for(int i=1;i<=n;i++)
    195         {
    196             if(dye[i]==-1)
    197                 to_dye(-1,i);
    198         }
    199 
    200         //printf("eee
    ");
    201 
    202         if(!flag)
    203         {
    204             printf("No
    ");
    205             continue;
    206         }
    207         else
    208         {
    209             build_graph(n);
    210             int flow=max_flow(n);
    211             printf("%d
    ",flow);
    212         }
    213     }
    214     return 0;
    215 }
    View Code
  • 相关阅读:
    DELPHI美化界面
    WebSevice相关
    Hotmail邮件接收
    DHTMLEdit
    Eclipse 基础
    POP3相关
    DELPHI中GIF的使用
    javaaop
    RAD Studio 2010 启动报错"displayNotification: 内存不够" 解决办法
    编程之道
  • 原文地址:https://www.cnblogs.com/-maybe/p/4693057.html
Copyright © 2011-2022 走看看