二分匹配_HDU_2389

来源:互联网 发布:透明国际2016最新数据 编辑:程序博客网 时间:2024/05/02 20:06

二分匹配,建图,hk算法,然道匈牙利算法要退休了?

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#define oo 0x3f3f3f3fconst int maxn = 3050;using namespace std;int t,n,m;struct node{    int x,y,speed;};struct edge{    int u,v,next;};int head[maxn],tot;edge e[maxn*maxn];node umbrella[maxn], guest[maxn];int cx[maxn],cy[maxn],dx[maxn],dy[maxn];int vis[maxn];bool can(node a, node b){    int dis,tt;    dis = (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);    tt = a.speed*a.speed*t*t;    if(tt >= dis)return true;    return false;}void add(int u, int v){    e[tot].u = u;    e[tot].v = v;    e[tot].next = head[u];    head[u] = tot++;}int searchpath()//增广路一条{    int dis = oo;    memset(dx, -1,sizeof(dx));    memset(dy, -1,sizeof(dy));    queue<int>Q;    for(int i = 1; i <= n; i++)    {        if(cx[i]==-1)        {            Q.push(i);            dx[i] = 0;        }    }    while(!Q.empty())    {        int u = Q.front();        Q.pop();        if(dx[u]>dis)break;        for(int i = head[u]; i != -1; i = e[i].next)        {            int v = e[i].v;            if(dy[v]==-1)//如果这个点还未走过            {                dy[v] = dx[u]+1;                if(cy[v]==-1)dis = dy[v];//如果未匹配,则直接匹配                else//有了就反回回去                {                    dx[cy[v]] = dy[v]+1;//匹配的那个点                    Q.push(cy[v]);                }            }        }    }    return dis != oo;}int dfs(int u){    for(int i = head[u]; i != -1; i = e[i].next)    {        int v = e[i].v;        if(!vis[v]&&dx[u]+1 == dy[v])        {            vis[v] = 1;            if(cy[v]==-1||dfs(cy[v]))            {                cy[v] = u;                cx[u] = v;                return 1;            }        }    }    return 0;}int Maxpath(){    int ret = 0;    memset(cx, -1,sizeof(cx));    memset(cy, -1,sizeof(cy));    while(searchpath())    {        memset(vis, 0, sizeof(vis));        for(int i = 1; i <= n; i++)            if(cx[i]==-1)                ret += dfs(i);    }    return ret;}void Init(){    memset(head, -1,sizeof(head));    tot = 0;    scanf("%d%d",&t,&n);    for(int i = 1; i <= n; i++)    {        scanf("%d%d%d",&guest[i].x,&guest[i].y,&guest[i].speed);    }    scanf("%d",&m);    for(int i = 1; i <= m; i++)    {        scanf("%d%d",&umbrella[i].x, &umbrella[i].y);    }    for(int i = 1; i <= n; i++)    {        for(int j = 1; j <= m; j++)        {            if(can(guest[i],umbrella[j]))            {                add(i,j);            }        }    }}int main(){    int t,ret;    scanf("%d",&t);    for(int ct = 1; ct <= t; ct++)    {        Init();        printf("Scenario #%d:\n%d\n\n",ct,Maxpath());    }    return 0;}
0 0