• LA4043


    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2044

    大致题意:

    平面上有n个白点和n个黑点,求一种完美匹配使他们间的连线不相交

    思路:要注意到,若有两种匹配相交,总能够当成对角线补成四边形,然后选四边形的两个边作为匹配就不会相交,并且一定匹配后的距离和缩短了,简单的几何知识,显然最小权匹配不会出现相交情况


    防止被卡精度用了龙龙

    //	Accepted	C++11	0.079
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <ctime>
    #include <bitset>
    #include <algorithm>
    #define SZ(x) ((int)(x).size())
    #define ALL(v) (v).begin(), (v).end()
    #define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
    #define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i)
    #define REP(i,n) for ( int i=1; i<=int(n); i++ )
    #define rep(i,n) for ( int i=0; i<int(n); i++ )
    using namespace std;
    typedef long long ll;
    #define X first
    #define Y second
    typedef pair<ll,ll> pii;
    
    template <class T>
    inline bool RD(T &ret) {
        char c; int sgn;
        if (c = getchar(), c == EOF) return 0;
        while (c != '-' && (c<'0' || c>'9')) c = getchar();
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0');
        while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return 1;
    }
    template <class T>
    inline void PT(T x) {
        if (x < 0) {
            putchar('-');
    
            x = -x;
        }
        if (x > 9) pt(x / 10);
        putchar(x % 10 + '0');
    }
    
    
    const int N = 100+10;
    const ll inf = 1LL<<50;
    pii poix[N],poiy[N];
    int n;
    ll mp[N][N];
    
    ll dis(int x,int y){
            ll a = poix[x].X-poiy[y].X, b = poix[x].Y-poiy[y].Y;
            return (a*a+b*b);
    }
    
    int link[N];
    ll lx[N],ly[N]; //y中各点匹配状态,x,y中的点标号
    ll sla[N];
    bool visx[N],visy[N];
    bool DFS(int x)
    {
            visx[x] = true;
            REP(y,n){
                    if(visy[y])continue;
                    ll tmp = lx[x] + ly[y] - mp[x][y];
                    if(tmp == 0){
                            visy[y] = true;
                            if(link[y] == -1 || DFS(link[y])){
                                    link[y] = x;
                                    return true;
                            }
                    }
                    else if(sla[y] > tmp) sla[y] = tmp;
            }
            return false;
    }
    ll KM()
    {
            memset(link,-1,sizeof(link));
            memset(ly,0,sizeof(ly));
            REP(i,n){
                    lx[i] = -inf;
                    REP(j,n) lx[i] = max(lx[i],mp[i][j]);
            }
            REP(x,n){
                    REP(i,n) sla[i] = inf;
                    while(true)
                    {
                            memset(visx,false,sizeof(visx));
                            memset(visy,false,sizeof(visy));
                            if(DFS(x)) break;
                            ll d = inf;
                            REP(i,n) if(!visy[i]) d = min(d,sla[i]);
                            REP(i,n){
                                    if(visx[i]) lx[i] -= d;
                                    if(visy[i])ly[i] += d;
                                    else sla[i] -= d;
                            }
                    }
            }
            ll res = 0;
            REP(i,n) if(link[i] != -1) res += mp[link[i]][i];
            return res;
    }
    
    int main(){
            bool flag = 0;
            while(~scanf("%d",&n)){
                    if(flag) puts("");
                    flag = 1;
                    REP(i,n) RD(poix[i].X),RD(poix[i].Y);
                    REP(i,n) RD(poiy[i].X),RD(poiy[i].Y);
                    REP(x,n) REP(y,n) mp[y][x] = -sqrt(dis(x,y))*10000000;
                    KM();
                    REP(i,n) printf("%d
    ",link[i]);
            }
            //Print a blank line between datasets.
    }
    


  • 相关阅读:
    冲刺五
    ubuntu安装utorrent
    struts2中properties属性
    Hadoop下的word count程序
    导入svn项目时eclipse崩溃
    Struts2 中jsp直接跳转到action
    用eclipse开发hadoop程序
    ubuntu下安装java
    【橙色警报】最新盗qq号方式,连我这个老鸟都一不小心被骗了
    在ubuntu上安装hadoop(书和官方文档结合的)
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7185995.html
Copyright © 2020-2023  润新知