zoukankan      html  css  js  c++  java
  • HDU-2389 Rain on your Parade

    数据较大,用成Hopcroft-Karp算法更合适。

    其实Hopcroft-Karp算法就是一开始通过DFS预处理出Dist标号,然后利用Dist标号实现同时查找多条最短增广路的目的。

    #include <cstdlib>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <queue>
    
    #define rep(i, l, r) for(int i=l; i<=r; i++)
    #define clr(x, c) memset(x, c, sizeof(x))
    #define N 3456
    #define MAX 1<<30
    
    using namespace std;
    int read()
    {
    	int x=0, f=1; char ch=getchar();
    	while (ch<'0' || ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
    	while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
    	return x*f;
    }
    
    struct edge{int y, n;} e[N*N]; int fir[N], en;
    struct node{int x, y, s;} g[N];
    int n, m, t, ans, k[N*2], d[N*2];
    int c[N*2];
    
    void Add(int x, int y) { en++, e[en].y=y, e[en].n=fir[x], fir[x]=en; }
    
    int Dist(int x1, int x2, int y1, int y2) { return (x2-x1)*(x2-x1)+(y1-y2)*(y1-y2); }
    
    bool Find(int x)
    {
    	int o=fir[x], y=e[o].y;
    	while (o)
    	{
    		if (!k[y] || (k[y] && d[x]==d[k[y]]-2 && Find(k[y]))) { k[y]=x; return true; }
    		o=e[o].n, y=e[o].y;
    	}
    	return false;
    }
    
    int main()
    {
    	int tt=0, T=read();
    	while (tt++ < T)
    	{
    		clr(fir, 0); clr(k, 0); en=ans=0; clr(c, 0);
    		t=read(); n=read(); rep(i, 1, n) g[i].x=read(), g[i].y=read(), g[i].s=read()*t;
    		m=read(); rep(j, 1, m) 
    		{
    			int x=read(), y=read();
    			rep(i, 1, n) if (Dist(g[i].x, x, g[i].y, y) <= g[i].s*g[i].s) Add(i, j+N);
    		}
    		while (ans<n)
    		{
    			queue <int> q; bool can=true;
    			rep(i, 1, n) if (!c[i]) q.push(i), d[i]=0; else d[i]=MAX;
    			while (!q.empty())
    			{
    				int x=q.front(), o=fir[x], y=e[o].y, dis=MAX; q.pop();
    				if (d[x]>dis) break;
    				while (o)
    				{
    					if (!k[y]) dis=d[x]; else if (d[k[y]]==MAX) d[k[y]]=d[x]+2, q.push(k[y]);
    					o=e[o].n, y=e[o].y;
    				}
    			}
    			rep(i, 1, n) if (!c[i] && Find(i)) c[i]=true, ans++, can=false;
    			if (can) break;
    		}
    		printf("Scenario #%d:
    %d
    
    ", tt, ans);
    	}
    }
  • 相关阅读:
    [POI2014]KUR-Couriers
    [题解向] Luogu4092 [HEOI2016/TJOI2016]树
    [探究] OI中各种初级数论算法相关
    [SCOI2005]骑士精神
    [intoj#7]最短距离
    数列分块入门
    动态规划问题基础
    Luogu P1967 货车运输
    Luogu P3379 【模板】最近公共祖先(LCA)
    Luogu P3378 【模板】堆
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4358109.html
Copyright © 2011-2022 走看看