• 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 }
  • 相关阅读:
    JAVA常用运算符
    JAVA基本语义简介
    JAVA常用关键字
    记事本写JAVA程序
    JAVA开发环境搭建
    PROTEL DXP原理图编译 常见错误与处理方法
    关于光耦的认识
    十六进制转十进制函数_C编程
    Protues记录文档_1
    SR触发器和JK触发器
  • 原文地址:https://www.cnblogs.com/mt522/p/5369910.html
Copyright © 2020-2023  润新知