hdu2389+二分匹配(Hopcroft-Karp算法)

题意很简单,显然是对客人与伞做匹配,求最大匹配数。

一开始用了匈牙利,果断TLE。。。

好吧,原来二分匹配还有这个奇葩算法。。然而敲完还是不明白这个算法啥意思。。。

附两个算法的时间复杂度:

匈牙利:O(VE)

H-K    :O(V^0.5 E)

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<queue>
  5 using namespace std;
  6 int nx,ny,mx[3300],my[3300],dx[3300],dy[3300],vis[3300];
  7 vector<int> v[3300];
  8 struct node1
  9 {
 10     int x,y,sp;
 11 }per[3300];
 12 struct node2
 13 {
 14     int x,y;
 15 }umb[3300];
 16 bool dfs(int u)
 17 {
 18     int v2,i;
 19     for(i=0;i<v[u].size();i++)
 20     {
 21         v2=v[u][i];
 22         if(!vis[v2]&&dy[v2]==dx[u]+1)
 23         {
 24             vis[v2]=1;
 25             if(my[v2]==-1||dfs(my[v2]))
 26             {
 27                 my[v2]=u;
 28                 mx[u]=v2;
 29                 return true;
 30             }
 31         }
 32     }
 33     return false;
 34 }
 35 int hkmatch()
 36 {
 37     int ret=0;
 38     memset(mx,-1,sizeof(mx));
 39     memset(my,-1,sizeof(my));
 40     while(true)
 41     {
 42         int i;
 43         bool flag=false;
 44         queue<int> q;
 45         memset(dx,0,sizeof(dx));
 46         memset(dy,0,sizeof(dy));
 47         for(i=1;i<=nx;i++)
 48         {
 49            if(mx[i]==-1)
 50             {
 51                 q.push(i);
 52             }
 53         }
 54         while(!q.empty())
 55         {
 56             int z=q.front();
 57             q.pop();
 58             for(i=0;i<v[z].size();i++)
 59             {
 60                 int vv=v[z][i];
 61                 if(!dy[vv])
 62                 {
 63                     dy[vv]=dx[z]+1;
 64                     if(my[vv]==-1) flag=true;
 65                     else
 66                     {
 67                         dx[my[vv]]=dy[vv]+1;
 68                         q.push(my[vv]);
 69                     }
 70                 }
 71             }
 72         }
 73         if(flag==false) break;
 74         memset(vis,0,sizeof(vis));
 75         for(i=1;i<=nx;i++)
 76         {
 77             if(mx[i]==-1&&dfs(i))
 78             ret++;
 79         }
 80     }
 81     return ret;
 82 }
 83 
 84 int main()
 85 {
 86     int cas,i,j,numcas=0;
 87     scanf("%d",&cas);
 88     while(cas--)
 89     {
 90         int t;
 91         scanf("%d",&t);
 92         scanf("%d",&nx);
 93         for(i=1;i<=nx;i++)
 94             v[i].clear();
 95         for(i=1;i<=nx;i++)
 96             scanf("%d%d%d",&per[i].x,&per[i].y,&per[i].sp);
 97         scanf("%d",&ny);
 98         for(i=1;i<=ny;i++)
 99             scanf("%d%d",&umb[i].x,&umb[i].y);
100         for(i=1;i<=nx;i++)
101         {
102             for(j=1;j<=ny;j++)
103             {
104                 if(per[i].sp*t*per[i].sp*t>=(per[i].x-umb[j].x)*(per[i].x-umb[j].x)+(per[i].y-umb[j].y)*(per[i].y-umb[j].y))
105                     v[i].push_back(j);
106             }
107         }
108         printf("Scenario #%d:
",++numcas);
109         printf("%d

",hkmatch());
110     }
111     return 0;
112 }
原文地址:https://www.cnblogs.com/mt522/p/5369910.html