poj 1034 The dog task

来源:互联网 发布:修改系统启动顺序软件 编辑:程序博客网 时间:2024/05/16 11:54

二分图的最大匹配。

建图的时候从主人路径上的前(n - 1)个点出发,枚举m个景点,能满足条件的连边,然后求最大匹配,输出路径就可以了。

/* * Author: stormdpzh * Created Time:  2012/9/11 20:14:45 * File Name: b.cpp */#include <iostream>#include <cstdio>#include <sstream>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <list>#include <algorithm>#include <functional>#define sz(v) ((int)(v).size())#define rep(i, n) for(int i = 0; i < n; i++#define repf(i, a, b) for(int i = a; i <= b; i++)#define repd(i, a, b) for(int i = a; i >= b; i--)#define out(n) printf("%d\n", n)#define mset(a, b) memset(a, b, sizeof(a))#define lint long longusing namespace std;const int INF = 1 << 30;const int MaxN = 105;const double eps = 1e-8;struct Node {    int x, y;    void read()    {        scanf("%d%d", &x, &y);     }};Node pnt[MaxN], dog[MaxN];int n, m;bool mp[MaxN][MaxN];int x[MaxN], y[MaxN];bool vis[MaxN];int sgn(double d){    if(d > eps) return 1;    if(d < -eps) return -1;    return 0;}bool check(int id1, int id2){    int xx = pnt[id1 + 1].x - pnt[id1].x;    int yy = pnt[id1 + 1].y - pnt[id1].y;    double total = xx * xx + yy * yy;     int xx1 = dog[id2].x - pnt[id1].x, xx2 = pnt[id1 + 1].x - dog[id2].x;    int yy1 = dog[id2].y - pnt[id1].y, yy2 = pnt[id1 + 1].y - dog[id2].y;    int total1 = xx1 * xx1 + yy1 * yy1;    int total2 = xx2 * xx2 + yy2 * yy2;    if(sgn(sqrt((double)total2) + sqrt((double)total1) - 2 * sqrt((double)total)) <= 0) return true;    return false;}bool find(int u){    for(int i = 0; i < m; i++) {        if(!vis[i] && mp[u][i]) {            vis[i] = true;            if(y[i] == -1 || find(y[i])) {                x[u] = i;                y[i] = u;                return true;            }        }    }    return false;}int gao(){    int match = 0;    memset(x, -1, sizeof(x));    memset(y, -1, sizeof(y));    for(int i = 0; i < n - 1; i++) {        if(x[i] == -1) {            memset(vis, false, sizeof(vis));            if(find(i)) match++;        }    }    return match;}int main(){    while(2 == scanf("%d%d", &n, &m)) {        for(int i = 0; i < n; i++) pnt[i].read();        for(int i = 0; i < m; i++) dog[i].read();            mset(mp, false);        for(int i = 0; i < n - 1; i++) {            for(int j = 0; j < m; j++) {                if(check(i, j)) mp[i][j] = true;             }        }        int res = gao();        printf("%d\n", res + n);        for(int i = 0; i < n - 1; i++) {            if(x[i] != -1) printf("%d %d %d %d ", pnt[i].x, pnt[i].y, dog[x[i]].x, dog[x[i]].y);            else printf("%d %d ", pnt[i].x, pnt[i].y);         }        printf("%d %d\n", pnt[n - 1].x, pnt[n - 1].y);    }    return 0;}