Rain on your Parade

来源:互联网 发布:nginx set 变量 编辑:程序博客网 时间:2024/06/05 07:00
这道题其实就是一个Hopcroft-Carp模板题
 匈牙利算法中,我们每次寻找一条增广路来增加匹配集合M.可以证明,每次找增广路的复杂度是O(E),一共需要增广O(V)次,因此总时间复杂度为O(VE).为了降低时间复杂度,在Hopcroft Karp算法中,我们在增加匹配集合M时,每次寻找多条增广路.可以证明,这样迭代次数最多为2*V^0.5,所以,时间复杂度就降到了O(V^0.5*E).
#include <iostream>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <vector>#include <queue>using namespace std;#define MAXN 3333const int INF=1<<28;int mx[MAXN], my[MAXN];int dx[MAXN], dy[MAXN];bool vis[MAXN];vector<int> g[MAXN];int nx, ny, t, dis;struct point{    int x, y, v;}umb[MAXN], peo[MAXN];bool dfs( int u ){    for( int i = 0; i < g[u].size(); i++)    {        int v = g[u][i];        if( !vis[v] && dy[v] == dx[u] + 1)        {            vis[v] = 1;//            if( my[v] != -1 && dy[v] == dis)//                 continue;            if( my[v] == -1 || dfs(my[v]))            {                my[v] = u;                mx[u] = v;                return true;            }        }    }    return false;}int solve(){    memset(mx, -1, sizeof(mx));    memset(my, -1, sizeof(my));    int ans = 0;    while(1)    {        queue<int > que;        memset(dx, -1, sizeof(dx));        memset(dy, -1, sizeof(dy));        //dis = INF;        for(int i = 1; i <= nx; i++)          if(mx[i] == -1) que.push(i), dx[i] = 0;        bool flag = false;        while(!que.empty())        {            int u = que.front();            que.pop();           // if(dx[u] > dis) break;            for( int i = 0; i < g[u].size(); i++)            {                int v = g[u][i];                if(dy[v] == -1)                {                    dy[v] = dx[u] + 1;                    if(my[v] == -1) //dis = dy[v];                        flag = true;                    else                    {                        dx[my[v]] = dy[v] + 1;                        que.push(my[v]);                    }                }            }        }        //if(dis == INF) break;        if(!flag) break;        memset(vis, 0, sizeof(vis));        for( int i = 1; i <= nx; i++)        {            if(mx[i] == -1 && dfs(i)) ans++;        }    }    return ans;}bool check( point a, point b){    if((a.x - b.x) * ( a.x - b.x) + (a.y - b.y) * (a.y - b.y) <= t*t*a.v*a.v)         return true;    return false;}int main(){    int T;    scanf("%d",&T);    int ca = 1;    while(T--)    {        scanf("%d",&t);        scanf("%d",&nx);        memset(g, 0, sizeof(g));        for( int i = 1; i <= nx; i++)            {               scanf("%d %d %d",&peo[i].x, &peo[i].y, &peo[i].v);               g[i].clear();            }        scanf("%d",&ny);        for( int i = 1; i <= ny; i++)            scanf("%d %d",&umb[i].x, &umb[i].y), umb[i].v = 0;        for( int i = 1; i <= nx; i++)          for( int j = 1; j <= ny; j++)            if(check(peo[i], umb[j]))                    g[i].push_back(j);        printf("Scenario #%d:\n",ca++);        int ans = solve();        printf("%d\n",ans);        printf("\n");    }    return 0;}

0 0