• 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
  • 相关阅读:
    傻逼Eclipse笔记
    Less笔记
    [转]解决WebClient或HttpWebRequest首次连接缓慢问题
    Css3图标库
    Json.Net4.5 序列化问题
    async和await
    CLR、内存分配和垃圾回收
    C#7.0新语法
    C#6.0新语法
    C#泛型详解
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/6592399.html
Copyright © 2020-2023  润新知