UVA 670 The dog task【二部图最大匹配 邻接表DFS】
来源:互联网 发布:淘宝信息管理系统建设 编辑:程序博客网 时间:2024/04/29 12:21
题目大意:题意百度。
解题策略:建立二部图模型,以人走的每段路与狗的兴趣点作二部图,求出该二部图对于狗的兴趣点的最大匹配数,加上人的路线,就是狗的路线,输出即可。
1,二部图最大匹配用邻接表实现,快速;
2,有个非常恶心的wa点,就是建立人的每段路与狗的兴趣点之间关系时,精度控制eps,若定义为1e-10 wa, 1e-20AC,wa了好久……浪费时间
/* UVA 670 The dog task AC by J_Dark ON 2013/4/20 Time 0.016s*/#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <vector>#include <algorithm>using namespace std;int perNodeNum, dogNodeNum;struct XY{int x, y;XY(int a=0, int b=0){ x=a, y=b;}double Distance(XY P){ return sqrt(((P.x-x)*(P.x-x)+ (P.y-y)*(P.y-y))*1.0);}};struct PER{ //人走的每段路XY u, v; //起点,终点double pathUV; //路的长度PER(XY a, XY b){ u=a; v=b; pathUV = u.Distance(v);}};vector <XY> perSonNode, dog; //人,狗坐标vector <PER> perSon; //人走的每段路程 //邻接表,存储与狗的兴趣点邻接的人走的段路程,即存放狗在某兴趣点时,它可以去往的全部人的段路程vector < vector<int> > reachedPer;//存放匹配边vector <int> pairDP;//是否匹配标记vector <bool> visited;/////////////////////////////////////void Initial(){perSon.clear();dog.clear();perSonNode.clear();reachedPer.clear();pairDP.clear();visited.clear();}void Input(){cin >> perNodeNum >> dogNodeNum;int x, y;for(int i=0; i<perNodeNum; i++){cin >> x >> y;perSonNode.push_back(XY(x,y));}for(int i=0; i<perSonNode.size()-1; i++){perSon.push_back( PER(perSonNode[i], perSonNode[i+1]) );}for(int i=0; i<dogNodeNum; i++){cin >> x >> y;dog.push_back(XY(x,y));}for(int i=0; i<perSon.size(); i++) pairDP.push_back(-1);}void Solve(){const double eps = 1e-20; //1e-10wa, 1e-20AC, uva此题数据强大,汗颜……vector<int> personPath;//寻找每个兴趣点,狗可以匹配的所有人的段路程,建立{狗兴趣点——人段路程}二部图for(int d=0; d<dog.size(); d++){personPath.clear();for(int p=0; p<perSon.size(); p++){ //人的路程集合标号// 狗的速度最大可达到人速度2倍,满足2*人路程 > 狗的路程, 即可建立关系if(2*perSon[p].pathUV - (dog[d].Distance(perSon[p].u) + dog[d].Distance(perSon[p].v)) > eps) personPath.push_back(p);}//将所有与d邻接的集合存入reachedPer.push_back(personPath);}}/////////////////////////////////////////////////////////////////匈牙利算法求二分图最大匹配bool findPath(int d){for(int i=0; i<reachedPer[d].size(); i++){int temp_p = reachedPer[d][i];if(!visited[temp_p]){visited[temp_p] = true;//若temp_p为未盖点 或者 从temp_p出发可以找到增广路if(pairDP[temp_p] == -1 || findPath(pairDP[temp_p])){pairDP[temp_p] = d; //交换匹配边与非匹配边,使最大匹配数+1return true;}}}//从d出发未找到增广路return false;}void MaxMatch(){int maxMatch = 0;for(int d=0; d<dog.size(); d++){visited.clear();visited.resize(perSon.size());if(findPath(d)) maxMatch++;}cout << maxMatch+perNodeNum << endl;int cc=0;for(int i=0; i<perSon.size(); i++){ if(cc > 0) cout << " "; cc++;cout << perSon[i].u.x << " " << perSon[i].u.y;if(pairDP[i] != -1){ cout << " " << dog[pairDP[i]].x << " " << dog[pairDP[i]].y;}}cout << " " << perSon[perSon.size()-1].v.x << " " << perSon[perSon.size()-1].v.y;cout << endl;}/////////////////////////////////////int main(){int testCase;while(cin >> testCase){getchar();getchar();for(int i=0; i<testCase; i++){ if(i>0) cout << endl; Initial(); Input(); Solve(); MaxMatch(); }}//system("pause");return 0;}
- UVA 670 The dog task【二部图最大匹配 邻接表DFS】
- ZJU2039 The Dog Task - 二部图最大匹配
- UVa670 - The dog task(最大二分匹配)
- uva 670The dog task
- uva 670 The dog task
- Place the Robots(二部图最大匹配,建图,匈牙利DFS增广)
- 二部图,最大匹配
- 二部图最大匹配
- 二部图最大匹配
- 匈牙利算法 DFS 二部图的最大匹配
- UVA 10080 Gopher II【简单二部图最大匹配】
- hdu2444 The Accomodation of Students(判断二部图+最大匹配)
- UVA 11045 My T-shirt suits me【二部图是否全匹配+DFS邻接矩阵实现】
- COURSES(裸二部图最大匹配)
- 二部图最大匹配--匈牙利算法
- 编程练习B(最大二部图匹配)
- uva 10122 Mysterious Mountain and ZOJ 1231 Mysterious Mountain (二分+二部图最大匹配)
- 最大二分图匹配 邻接表优化
- asmcmd
- 批量查询已经创建的用户,密码和授权
- spring mvc处理表单提交
- i 的 n 次幂 是 sum
- Andriod中Style/Theme原理以及Activity界面文件选取过程浅析
- UVA 670 The dog task【二部图最大匹配 邻接表DFS】
- 遗传算法求解TSP问题
- 搜索是电商必争之家
- ESB学习笔记(Spring Integration实战)
- 工大之行
- vc编译最小文件
- [AS3进阶讨论区] 同志们,这些知识点你们知道多少?
- 利用WeakHashMap避免因缓存条目过期而造成的内存泄漏问题
- 编程语言中的闭包