hdu 2389

来源:互联网 发布:网络维护主要做什么 编辑:程序博客网 时间:2024/05/17 12:03

这题明显的二分匹配 第一次用匈牙利算法居然TLE。。。。

然后改用HK A了 156ms~

图用的邻接表存的,没用vector,可能快点吧。。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>


using namespace std;


int n,m,head[3001],speed[3001],next[9000001],e[9000001],matchx[3001],matchy[3001],dx[3001],dy[3001];
struct point{
    int x,y;
} man[3001],unbrella[3001];


bool bfs(){
    memset(dx,0,sizeof(int)*(m+1));
    memset(dy,0,sizeof(int)*(n+1));
    bool find = false;
    queue<int> q;
    for(int i = 1;i<=m;i++) if(matchx[i]==-1) q.push(i);
    while(!q.empty()){
        int x = q.front();q.pop();
        for(int i = head[x];i!=-1;i = next[i]){
            int y = e[i];
            if(!dy[y]){
                dy[y] = dx[x]+1;
                if(matchy[y]==-1) find = true;
                else{
                    dx[matchy[y]] = dy[y] + 1;
                    q.push(matchy[y]);
                }
            }
        }
    }
    return find;
}


bool find(int u){
    for(int i = head[u];i!=-1;i = next[i]){
        int v = e[i];
        if(dy[v]==dx[u]+1){
            dy[v] = 0;
            if(matchy[v]==-1||find(matchy[v])){
                matchy[v] = u;
                matchx[u] = v;
                return true;
            }
        }
    }
    return false;
}


int HK(){
    memset(matchx,-1,sizeof(int)*(m+1));
    memset(matchy,-1,sizeof(int)*(n+1));
    int ans = 0;
    while(bfs()){
        for(int i = 1;i<=m;i++){
            if(matchx[i]==-1&&find(i)) ans++;
        }
    }
    return ans;
}


inline int d(int i,int j){
    point &mm = man[i];
    point &un = unbrella[j];
    return (mm.x-un.x)*(mm.x-un.x)+(mm.y-un.y)*(mm.y-un.y);
}


inline void addEdge(int &count,int u,int v){
    e[count] = v;
    int temp = head[u];
    head[u] = count;
    next[count++] = temp;
}


int main(void){
    //freopen("D:\\data.txt","r",stdin);
    int ca;
    scanf("%d",&ca);
    for(int tt = 1;tt<=ca;tt++){
        int t;
        scanf("%d",&t);
        scanf("%d",&m);
        memset(head,-1,sizeof(int)*(m+1));
        int count=0;
        for(int i = 0;i<m;i++)
            scanf("%d %d %d",&man[i].x,&man[i].y,&speed[i]);
        scanf("%d",&n);
        for(int i = 0;i<n;i++)
            scanf("%d %d",&unbrella[i].x,&unbrella[i].y);
        for(int i = 0;i<m;i++){
            for(int j = 0;j<n;j++){
                int dis = d(i,j);
                if(dis<=t*t*speed[i]*speed[i])
                    addEdge(count,i+1,j+1);
            }
        }
        int ans = HK();
        printf("Scenario #%d:\n%d\n\n",tt,ans);
    }
}

原创粉丝点击