zoukankan      html  css  js  c++  java
  • hdu2389 Rain on your Parade 二分图匹配--HK算法

    You’re giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is here. It’s a warm, sunny evening, and a soothing wind sends fresh, salty air from the sea. The evening is progressing just as you had imagined. It could be the perfect end of a beautiful day.

    But nothing ever is perfect. One of your guests works in weather forecasting. He suddenly yells, “I know that breeze! It means its going to rain heavily in just a few minutes!” Your guests all wear their best dresses and really would not like to get wet, hence they stand terrified when hearing the bad news.
    You have prepared a few umbrellas which can protect a few of your guests. The umbrellas are small, and since your guests are all slightly snobbish, no guest will share an umbrella with other guests. The umbrellas are spread across your (gigantic) garden, just like your guests. To complicate matters even more, some of your guests can’t run as fast as the others.
    Can you help your guests so that as many as possible find an umbrella before it starts to pour? 

    Given the positions and speeds of all your guests, the positions of the umbrellas, and the time until it starts to rain, find out how many of your guests can at most reach an umbrella. Two guests do not want to share an umbrella, however. 

    虽然也是二分图匹配,但是需要用HK算法,匈牙利算法会超时

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<queue>
      4 using namespace std;
      5 typedef long long ll;
      6 const int MAXN=3005;//最大点数
      7 const int INF=0x3f3f3f3f;//距离初始值
      8 int Map[MAXN][MAXN];//二分图
      9 int cx[MAXN];//cx[i]表示左集合i顶点所匹配的右集合的顶点序号
     10 int cy[MAXN];//cy[i]表示右集合i顶点所匹配的左集合的顶点序号
     11 int n,m,dis;
     12 int dx[MAXN],dy[MAXN];
     13 bool vis[MAXN];
     14 int xp[3005],yp[3005],s[3005];
     15 int xu[3005],yu[3005];
     16 
     17 bool searchpath(){
     18     queue<int>Q;
     19     dis=INF;
     20     memset(dx,-1,sizeof(dx));
     21     memset(dy,-1,sizeof(dy));
     22     for(int i=1;i<=n;++i){
     23         //cx[i]表示左集合i顶点所匹配的右集合的顶点序号
     24         if(cx[i]==-1){
     25             //将未遍历的节点入队并初始化次节点距离为0
     26             Q.push(i);
     27             dx[i]=0;
     28         }
     29     }
     30     //广度搜索增广路径
     31     while(!Q.empty()){
     32         int u=Q.front();
     33         Q.pop();
     34         if(dx[u]>dis)break;
     35         //取右侧节点
     36         for(int i=1;i<=m;++i){
     37             //右侧节点的增广路径的距离
     38             if(Map[u][i]&&dy[i]==-1){
     39                 dy[i]=dx[u]+1;//v对应的距离为u对应距离加1
     40                 if(cy[i]==-1)dis=dy[i];
     41                 else{
     42                     dx[cy[i]]=dy[i]+1;
     43                     Q.push(cy[i]);
     44                 }
     45             }
     46         }
     47     }
     48     return dis!=INF;
     49 }
     50 
     51 //寻找路径深度搜索
     52 int findpath(int s){
     53     for(int i=1;i<=m;++i){
     54         //如果该点没有被遍历过并且距离为上一节点+1
     55         if(!vis[i]&&Map[s][i]&&dy[i]==dx[s]+1){
     56             //对该点染色
     57             vis[i]=1;
     58             if(cy[i]!=-1&&dy[i]==dis)continue;
     59             if(cy[i]==-1||findpath(cy[i])){
     60                 cy[i]=s;cx[s]=i;
     61                 return 1;
     62             }
     63         }
     64     }
     65     return 0;
     66 }
     67 
     68 //得到最大匹配的数目
     69 int MaxMatch(){
     70     int res=0;
     71     memset(cx,-1,sizeof(cx));
     72     memset(cy,-1,sizeof(cy));
     73     while(searchpath()){
     74         memset(vis,0,sizeof(vis));
     75         for(int i=1;i<=n;++i){
     76             if(cx[i]==-1)res+=findpath(i);
     77         }
     78     }
     79     return res;
     80 }
     81 
     82 int main(){
     83     int T;
     84     scanf("%d",&T);
     85     for(int q=1;q<=T;++q){
     86         memset(Map,0,sizeof(Map));
     87         int t;
     88         scanf("%d",&t);
     89         scanf("%d",&n);
     90         for(int i=1;i<=n;++i){
     91             scanf("%d%d%d",&xp[i],&yp[i],&s[i]);
     92         }
     93         scanf("%d",&m);
     94         for(int i=1;i<=m;++i){
     95             scanf("%d%d",&xu[i],&yu[i]);
     96         }
     97         for(int i=1;i<=n;++i){
     98             for(int j=1;j<=m;++j){
     99                 if((xp[i]-xu[j])*(ll)(xp[i]-xu[j])+(yp[i]-yu[j])*(ll)(yp[i]-yu[j])<=t*(ll)t*s[i]*s[i]){
    100                     Map[i][j]=1;
    101                 }
    102             }
    103         }
    104         printf("Scenario #%d:
    %d
    
    ",q,MaxMatch());
    105     }
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    java将Thu Jun 11 00:00:00 CST 2020类型转换为正常的时间类型
    SSM中JSP和thymeleaf同时使用
    java中thymeleaf获取项目根路径
    使用position:fixed定位的DIV元素,如何使其居中
    HTML设置textarea不可拖动
    使用js让Html页面弹出小窗口
    wow.js – 让页面滚动更有趣,使用方法
    CSS修改文本框placeholder提示的文字颜色
    JS监听用户按下ESC
    当div内所有元素都是浮动的时候,让容器(div)自动适应高度
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/6592399.html
Copyright © 2011-2022 走看看