• hdu 2444 The Accomodation of Students 判断是否构成二分图 + 最大匹配


      此题就是求最大匹配。不过需要判断是否构成二分图。判断的方法是人选一点标记为红色(0),与它相邻的点标记为黑色(1),产生矛盾就无法构成二分图。声明一个vis[],初始化为-1。通过深搜,相邻的点不满足异或关系就结束。如果没被标记,就标记为相邻点的异或。

      

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 const int N=205,INF=0x3f3f3f3f;
      8 int bmap[N][N],cx[N],cy[N],dx[N],dy[N];
      9 bool bmask[N];
     10 int flag,vis[N];
     11 int nx,ny,dis,ans;
     12 bool searchpath()
     13 {
     14     queue<int> q;
     15     dis=INF;
     16     memset(dx,-1,sizeof(dx));
     17     memset(dy,-1,sizeof(dy));
     18     for(int i=1;i<=nx;i++)
     19     {
     20         if(cx[i]==-1){ q.push(i); dx[i]=0; }
     21         while(!q.empty())
     22         {
     23             int u=q.front(); q.pop();
     24             if(dx[u]>dis) break;
     25             for(int v=1;v<=ny;v++)
     26             {
     27                 if(bmap[u][v]&&dy[v]==-1)
     28                 {
     29                     dy[v]= dx[u] + 1;
     30                     if(cy[v]==-1) dis=dy[v];
     31                     else
     32                     {
     33                         dx[cy[v]]= dy[v]+1;
     34                         q.push(cy[v]);
     35                     }
     36                 }
     37             }
     38         }
     39     }
     40     return dis!=INF;
     41 }
     42 int findpath(int u)
     43 {
     44     for(int v=1;v<=ny;v++)
     45     {
     46         if(!bmask[v]&&bmap[u][v]&&dy[v]==dx[u]+1)
     47         {
     48             bmask[v]=1;
     49             if(cy[v]!=-1&&dy[v]==dis) continue;
     50             if(cy[v]==-1||findpath(cy[v]))
     51             {
     52                 cy[v]=u; cx[u]=v;
     53                 return 1;
     54             }
     55         }
     56     }
     57     return 0;
     58 }
     59 void maxmatch()
     60 {
     61     ans=0;
     62     memset(cx,-1,sizeof(cx));
     63     memset(cy,-1,sizeof(cy));
     64     while(searchpath())
     65     {
     66         memset(bmask,0,sizeof(bmask));
     67         for(int i=1;i<=nx;i++)
     68             if(cx[i]==-1) ans+=findpath(i);
     69     }
     70 }
     71 void init()
     72 {
     73     memset(bmap,0,sizeof(bmap));
     74 }
     75 void dfs(int u)
     76 {
     77     for(int i=1;i<=nx&&!flag;i++)
     78     {
     79         if(u==i) continue;
     80         if(bmap[u][i]){
     81             if(vis[i]!=-1&&(vis[u]^vis[i]!=1)) flag=1;
     82             if(vis[i]==-1) {vis[i]=vis[u] ^1;dfs(i);}
     83         }
     84     }
     85 }
     86 int main()
     87 {
     88     //freopen("test.txt","r",stdin);
     89     int cas,i,j,k,m,n;
     90     while(scanf("%d%d",&n,&m)!= EOF)
     91     {
     92         init();
     93         memset(vis,-1,sizeof(vis));
     94         flag=0;
     95         for(i=1;i<=m;i++)
     96         {
     97             scanf("%d%d",&j,&k);
     98             bmap[j][k]=1;
     99         }
    100         nx=ny=n;
    101         vis[1]=0;
    102         dfs(1);
    103         if(flag) {printf("No
    ");continue;}
    104         maxmatch();
    105         printf("%d
    ",ans);
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    20165339 预备作业3 Linux安装及学习
    20165339 学习基础和c语言基础调查
    20165339 我期望的师生关系
    2018-2019-1 20165332 《信息安全系统设计基础》第3周学习总结
    2018-2019-1 20165332 《信息安全系统设计基础》第2周学习总结
    2018-2019-1 20165332 《信息安全系统设计基础》第1周学习总结
    20165332 2017-2018-2《Java程序设计》课程总结
    20165332实验五 网络编程与安全
    20165332实验四 Android开发基础
    20165332第十周课下作业
  • 原文地址:https://www.cnblogs.com/Potato-lover/p/3985869.html
Copyright © 2020-2023  润新知