int shortestDistance(int xMe, int yMe, int xHome, int yHome, vector <string> teleports) {
#if 1
		PVec points;
		points.push_back(P(xMe, yMe));
		points.push_back(P(xHome, yHome));
		PPMap warp;
		int i;
		for (i = 0; i < (int)teleports.size(); ++i) {
			istringstream s(teleports[i]);
			P p1, p2;
			s >> p1.first >> p1.second >> p2.first >> p2.second;
			points.push_back(p1);
			points.push_back(p2);
			warp[p1] = p2;
			warp[p2] = p1;
		}
		LLV Done(points.size());

		PLLMap Costs;
		LL total = 0;
		int min_index = 0;
		while (min_index != 1) {
			Done[min_index] = 1;
			P Last = points[min_index];
			LL min_cost = INF;
			for (i = 1; i < (int)points.size(); ++i) {
				if (Done[i]) {
					continue;
				}
				LL prev = Costs[points[i]];
				LL d = Distance(Last, points[i]);
				PPMap::const_iterator it = warp.find(points[i]);
				if (it != warp.end()) {
					LL w = 10 + Distance(Last, it->second);
					d = min(d, w);
				}
				LL cost = total + d;
				if (!prev || cost < prev) {
					Costs[points[i]] = cost;
				} else {
					cost = prev;
				}
				if (cost < min_cost) {
					min_index = i;
					min_cost = cost;
				}
			}
			total = min_cost;
		}

		return (int)total;
#else
		P Me(xMe, yMe);
		P Home(xHome, yHome);
		PVec pv1, pv2;
		LLV GoalCost;

		int i, j;
		for (i = 0; i < (int)teleports.size(); ++i) {
			int x1, y1, x2, y2;
			if (sscanf(teleports[i].c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2) != 4) {
				return -1;
			}
			pv1.push_back(P(x1, y1));
			pv2.push_back(P(x2, y2));
			// teleport + walk to goal
			GoalCost.push_back(10 + Distance(*pv2.rbegin(), Home));
			pv1.push_back(P(x2, y2));
			pv2.push_back(P(x1, y1));
			GoalCost.push_back(10 + Distance(*pv2.rbegin(), Home));
		}

		bool f = true;
		while (f) {
			f = false;
			for (i = 0; i < (int)pv1.size(); ++i) {
				for (j = 0; j < (int)pv1.size(); ++j) {
					if (i == j) {
						continue;
					}
					// teleport + walk to anther spot + teleport
					LL cost = 10 + Distance(pv2[i], pv1[j]) + GoalCost[j];
					if (cost < GoalCost[i]) {
						f = true;
						GoalCost[i] = cost;
					}
				}
			}
		}

		LL Min = Distance(Me, Home);
		for (i = 0; i < (int)pv1.size(); ++i) {
			Min = min(Min, Distance(Me, pv1[i]) + GoalCost[i]);
		}
		return (int)Min;
#endif
	}
Exemple #2
0
int main()
{
    using jlt::operator<<;
    using std::cout;
    using std::cerr;
    using std::endl;
    using std::setw;

    typedef jlt::mathmatrix<int>			Mat;
    typedef std::vector<int>			Vec;
    typedef jlt::polynomial<int>			Poly;
    typedef std::vector<Poly>			PVec;
    typedef std::vector<Mat>			MVec;
    typedef long long int				llint;


#if 1
    std::ifstream indata;
    indata.open("polycoeffs_n=7.m");
    const int n = 7;

    PVec pl;

    // Read in Mathematica file of polynomials.
    skipstring(indata,
               "(* Created by Wolfram Mathematica ??? : www.wolfram.com *)");
    skipstring(indata,"{");

    do
    {
        skipstring(indata,"{");

        Poly p;

        for (int i = n; i >= 0; --i)
        {
            indata >> p[i];
            if (i > 0) skipstring(indata,",");
        }
        skipstring(indata,"}");
        pl.push_back(p);
    }
    while (skipstring(indata,","));

    Poly p = pl[0];

#else
    const int n = 4;

    Poly p;
    p[0] = 1;
    p[n] = 1;
    p[n/2] = -1;
    p[n/2+1] = -1;
    p[n/2-1] = -1;
#endif

    int tr = -p[n-1];

    cerr << "Checking polynomial " << p;
    double lambdamax = findroot(p,2.0,1e-8);
    cerr << " with root  " << lambdamax << endl;

    // Create lower-triangle of matrices.
    MVec Alow;
    // Vector of positions of the "1" entry.
    // 0 <= al[k] <= k+1.  al[k]=k+1 corresponds to no 1 at all.
    Vec al(n), almax(n);
    for (int k = 0; k < n; ++k) almax[k] = k+1;
    do
    {
        Mat A(n,n);
        int trA = 0;
        for (int k = 0; k < n; ++k)
        {
            if (al[k] < k+1) A(k,al[k]) = 1;
            if (al[k] == k) ++trA;
        }
        if (trA == tr) Alow.push_back(A);
    }
    while(increment_vector(al,almax));

    cerr << Alow.size() << " lower-triangular forms\n";
    int todo = Alow.size();

    //
    // Upper-triangle of matrices: find valid patterns
    //
    int Nup = (n*(n-1))/2;
    Vec aup(Nup), aupmax(Nup);
    for (int k = 0; k < Nup; ++k) {
        aupmax[k] = 1;
    }
    // Make index pair for eack k.
    Vec rowidx(Nup), colidx(Nup);
    {
        int row = 0, col = 1;
        for (int k = 0; k < Nup; ++k)
        {
            rowidx[k] = row;
            colidx[k] = col++;
            if (col == n) {
                ++row;
                col = row+1;
            }
        }
    }

    llint N = 0;
    llint validpatterns = 0;
    llint reduciblepatterns = 0;
    llint rootexceeded = 0;

    cout << "{\n";
    bool thefirst = true;

    for (int li = 0; li < (int)todo; ++li)
    {
        cerr << "Lower-triangular form " << setw(4) << li+1 << ": ";

        // Vector of allowable patterns.
        std::vector<Vec> pattern;
        int n1min = -1, n1max = -1;

        do
        {
            // Form matrix.
            Mat A(Alow[li]);
            for (int k = 0; k < Nup; ++k) A(rowidx[k],colidx[k]) = aup[k];

            ++N;

            if (spectral_radius(A) <= lambdamax)
            {
                if (!A.isReducible())
                {
                    ++validpatterns;
                    pattern.push_back(aup);
                    int n1 = std::count(aup.begin(),aup.end(),1);
                    if (n1 < n1min || n1min == -1) n1min = n1;
                    if (n1 > n1max || n1max == -1) n1max = n1;
                }
                else
                {
                    ++reduciblepatterns;
                }
            }
            else
            {
                ++rootexceeded;
            }
        }
        while(increment_vector(aup,aupmax));

        cerr << setw(5) << pattern.size() << " valid patterns";

        // Skip lower-triangular forms with no allowable patterns.
        if (pattern.empty()) {
            cerr << endl;
            continue;
        }

        cerr << " (size ";
        int Alownorm = matrix_norm(Alow[li]);
        cerr << setw(2) << n1min+Alownorm << " to ";
        cerr << setw(2) << n1max+Alownorm << ")\n";

        for (int pa = 0; pa < (int)pattern.size(); ++pa)
        {
            // How many 1's in this pattern?
            int Npat = std::count(pattern[pa].begin(),pattern[pa].end(),1);
            // Make index pair for eack k.
            Vec patrowidx(Npat), patcolidx(Npat);
            {
                int row = 0, col = 1, m = 0;
                for (int k = 0; k < (n*(n-1))/2; ++k)
                {
                    if (pattern[pa][k] == 1)
                    {
                        patrowidx[m] = row;
                        patcolidx[m] = col;
                        ++m;
                    }
                    if (++col == n) {
                        ++row;
                        col = row+1;
                    }
                }
            }

            // Form matrix.
            // Start with the pattern equal to all ones.
            Mat A(Alow[li]);
            for (int k = 0; k < Npat; ++k) A(patrowidx[k],patcolidx[k]) = 1;

            // Now loop over vales of the entries of the pattern
            do
            {
                ++N;

                // Compute characteristic polynomial.
                Poly cpoly(A.charpoly());

                if (cpoly == p)
                {
                    cerr << "Got it!\n";
                    if (!thefirst) cout << "," << endl;
                    else thefirst = false;
                    A.printMathematicaForm(cout);
                }
            }
            while(increment_upper_triangle(A,patrowidx,patcolidx,lambdamax));
        }
    }


    cout << "\n}\n";

    cerr << validpatterns << endl;
    cerr << reduciblepatterns << endl;
    cerr << rootexceeded << endl;
    cerr << N << endl;
}