uva 670The dog task

来源:互联网 发布:泛微协同软件 编辑:程序博客网 时间:2024/06/05 18:29

题意:主人和狗散步,主人走的路都是一段一段的线段,狗想要去有趣的地方,但是要在主人线路上的每个顶点处与主人汇合,而且每次最多只能去一个地方,狗的速度是主人速度的两倍。给定主人的路线(一些坐标点)和狗想去的有趣的地方,求出狗最多能走的路线上的顶点数,并且将这些点打印出来。

分析:对于每一段线段,狗和主人同时出发,然后在另一个端点汇合,其中就看有没有有趣的地方可以去,并且在规定时间里赶回来,也就是狗的路径长度  <=  主人的路径长度的2倍,然后构造二部图,集合X中是线段,集合Y中是点,如果点到两线段端点的距离之和 <= 线段的长度 ,就建立联系。套用匈牙利算法。

WA教训:依然是下标范围出错,没有对上号,由边找点,link是点指向边, 范围是点的范围,antiLink是反过来记录的,所以范围是边的范围。

存储方式:连接表。有点节省空间和时间,链接矩阵中有很多空联系,值是0,在存储和查找时都会浪费。链接表中只有存在的联系,可以节省空间和时间。

匈牙利算法时间节省的方法:匈牙利的算法有两层循环,将个数少的集合放在第一层循环可以节省时间,不过这也取决于连接表怎么建立的。

代码:

//uva670 The dog task//AC By Warteac//2013-4-21//Runtime:0.016#include<iostream>#include<vector>#include<cmath>using namespace std;//////////////////////////struct node{int x;int y;node(int a = 0,int b = 0){x = a; y = b;}double distance(node n){return sqrt((double)(x-n.x)*(x-n.x)+(y-n.y)*(y-n.y));}double distance(node n1,node n2){return sqrt((double)(x-n1.x)*(x-n1.x)+(y-n1.y)*(y-n1.y)) + sqrt((x-n2.x)*(x-n2.x)+(y-n2.y)*(y-n2.y));}void printNode(){cout << x <<" "<< y;}};class TheDogTask{private:vector < vector <int> > map;//邻接表int numOfBobRoute;int numOfDogRoute;vector <node> bobRoute;vector <node> dogRoute;private:int matched;vector <int> link;//从 dogRoute 到 bobRoutevector <int> antiLink;//从bobRoute 到 dogRoutevector <bool> visited;bool dfs(int u);//寻找增广路径public:void initial();void readCase();void computing();void outResult();};void TheDogTask::initial(){map.clear();bobRoute.clear();dogRoute.clear();link.clear();antiLink.clear();visited.clear();numOfBobRoute = 0;numOfDogRoute = 0;matched = 0;}void TheDogTask::readCase(){int n , m,x,y;double dis;vector <int> route;cin >> n >> m;numOfBobRoute = n;numOfDogRoute = m;while(n--){cin >> x >> y;bobRoute.push_back(node(x,y));}while(m--){cin >> x >> y;dogRoute.push_back(node(x,y));}for(int i = 0; i < numOfBobRoute - 1; i++){//遍历每条边dis = bobRoute[i].distance(bobRoute[ i+1 ]);route.clear();//CLEARfor(int j = 0; j < numOfDogRoute; j++){//遍历每个有趣的地方if(dogRoute[j].distance(bobRoute[i],bobRoute[ i+1 ]) <= 2 * dis){route.push_back(j);//编号为j的地方dog可以去}}map.push_back(route);//建立一行记录}}bool TheDogTask::dfs(int u){for(int j = 0; j < map[u].size(); j++){//cout << " j = " << j <<endl;int t = map[u][j];if(!visited[t]){visited[t] = true;if(link[t] == -1 || dfs(link[t]) == true){link[t] = u;antiLink[u] = t;return true;}}}return false;//退出循环后才return false-WA;}void TheDogTask::computing(){//hungaryfor(int x = 0; x < numOfDogRoute; x++)link.push_back(-1);for(int x = 0; x < map.size(); x++)//antiLink的大小和link的大小不同-WAantiLink.push_back(-1);for(int i = 0; i < map.size(); i++){//cout << " i = " << i <<endl;visited.clear();visited.resize(numOfDogRoute);if(dfs(i)) matched++;}}void TheDogTask::outResult(){/*for (int i = 0; i < map.size(); i++){for (int j = 0; j < map[i].size(); j++){cout << map[i][j] << " ";}cout << endl;}*/cout << matched + numOfBobRoute << endl;bobRoute[0].printNode();for(int i = 0; i < map.size(); i++){if(antiLink[i] != -1){    cout << " ";dogRoute[antiLink[i]].printNode();}cout << " ";bobRoute[i+1].printNode();}cout << endl;}//////////////////////////int main(){TheDogTask dt;int n,m = 0;cin >> n;while(n--){m++;dt.initial();dt.readCase();dt.computing();if(m > 1) cout << endl;dt.outResult();}}


 

 

原创粉丝点击