标签:des style http io ar color os sp for
对应HDU题目:点击打开链接
Time Limit: 3000MS | Memory Limit: 165535KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
2 1 2 1 0 3 3 0 3 2 4 0 6 0 1 2 1 1 2 3 3 2 2 2 2 4 4
Sample Output
Scenario #1: 2 Scenario #2: 2
Source
题意:在一个二维坐标系上有n个人和m把伞,每个人都有自己的移动速度,问最多有多少人可以再t min内移动到不同的雨伞处(不允许两个人共用一把伞)。
思路:很明显是二分图的最大匹配问题,用普通DFS,BFS匈牙利算法妥当TLE,之后学了Hopcroft-Karp算法后回来再做;
有点奇怪的是用邻接矩阵无论是效率或空间都比邻接表或vector要好。。。
贴上邻接表代码:
#include<cstdio> #include<cstdlib> #include<cmath> #include<map> #include<queue> #include<stack> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<iostream> #define ms(x,y) memset(x,y,sizeof(x)) const int MAXN=3000+10; const int MAX=9000000+10; const int INF=1<<30; using namespace std; int time,n,m; int speed[MAXN]; int head[MAXN]; int vis[MAXN]; int dx[MAXN]; int dy[MAXN]; int link_l[MAXN]; int link_r[MAXN]; int dis; struct Edge { int v,next; }E[MAX]; struct COOR { int x,y; }N[MAXN], M[MAXN]; bool Search() { queue<int>q; dis = INF; ms(dx, -1); ms(dy, -1); for(int i = 0; i<n; i++) if(link_r[i] == -1){//未匹配点入队,该点层次为0 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){//v是未匹配点 dy[v] = dx[u] + 1; if(link_l[v] == -1) dis = dy[v];//找到一条最小增广路 else{ dx[link_l[v]] = dy[v] + 1; q.push(link_l[v]); } } } } return dis != INF; } int dfs(int u) { for(int i=head[u]; i != -1; i = E[i].next){ int v = E[i].v; if(!vis[v] && dy[v] == dx[u] + 1){ vis[v] = 1; if(link_l[v] != -1 && dy[v] == dis) continue;//层次(也就是增广路径的长度)大于本次查找的dis,是searchP被break的情况,也就是还不确定是否是增广路径,只有等再次调用searchP()在判断。 if(link_l[v] == -1 || dfs(link_l[v])){ link_l[v] = u; link_r[u] = v; return 1; } } } return 0; } int MaxMatch() { int res = 0; ms(link_l, -1); ms(link_r, -1); while(Search()) { ms(vis, 0); for(int i=0; i<n; i++) if(link_r[i] == -1) res += dfs(i); } return res; } int main() { //freopen("in.txt","r",stdin); int T, w = 0;; scanf("%d", &T); while(T--) { ms(head, -1); int size = 0; scanf("%d%d", &time, &n); for(int i=0; i<n; i++) scanf("%d%d%d", &N[i].x, &N[i].y, &speed[i]); scanf("%d", &m); for(int i=0; i<m; i++) scanf("%d%d", &M[i].x, &M[i].y); for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ if((N[i].x - M[j].x) * (N[i].x - M[j].x) + (N[i].y - M[j].y) * (N[i].y - M[j].y) <= time * speed[i] * time * speed[i]){ E[size].v = j; E[size].next = head[i]; head[i] = size++; } } } printf("Scenario #%d:\n%d\n\n", ++w, MaxMatch()); } return 0; }
二分图最大匹配hopcroft-karp算法——HDU 2389
标签:des style http io ar color os sp for
原文地址:http://blog.csdn.net/u013351484/article/details/41944745