Advanced Guide to Algorithmic Competition 2.7 Astar

178. K Short Circuit

Given N points (numbered 1,2... Directed graph with M edges, find the length of K short circuit from starting point S to ending point T. Path allows repetition of passing points or edges.
Note: Each shortest path should contain at least one edge.

Input format
The first line contains two integers N and M.
Next, M lines, each containing three integers A,B and L, indicate that there is a directed edge between point A and point B, and the edge length is L.
The last line contains three integers S,T and K, representing the start S, end T and K short circuits, respectively.

Output format
Output takes up one line and contains an integer representing the length of K short circuit. If K short circuit does not exist, output "- 1".

Data Scope
1≤S,T≤N≤1000,
0≤M≤105,
1≤K≤1000,
1≤L≤100

Input sample:
2 2
1 2 5
2 1 4
1 2 2

Output sample:
14

/*
A* star

In the shortest path problem, if all edge weights are non-negative, then heuristic functions can be used to optimize the BFS process.

Heuristic function:
dist + f(s)
As long as f (s) <= g (s) (and monotonicity), it can be guaranteed that when a state s first emerges from the priority queue, its distance must be the shortest.

1.Establish the inverse graph, and then find the shortest distance from the end point T to all other points on the inverse graph as the evaluation function of each point.
2.Starting from the starting point S, each time the lowest point of the current estimate is taken out and all the points it can extend to are expanded. Estimated value = the starting point of distance is the real distance + valuation function
3.When K encounters T for the first time, the K short circuit from S to T is found.
*/

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

typedef pair<int, int> PII;
typedef pair<int, PII> PIII;

const int N = 1010, M = 200010;

int n, m;
int h[N], rh[N], e[M], w[M], ne[M], idx;
int dist[N], f[N], st[N]; //Number of Value Repetitions at the Shortest Distance Point to Each Point
int S, T, K;

void add(int *h, int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}

void dijkstra()
{
    priority_queue<PII, vector<PII>, greater<PII>> heap; //Small root pile
    memset(dist, 0x3f, sizeof dist);
    dist[T] = 0; //Finding the Shortest Distance by Reverse Graph
    heap.push({0, T});
    
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        
        int ver = t.second;
        if(st[ver]) continue;
        st[ver] = 1;
        
        for(int i = rh[ver]; ~i; i = ne[i]) //The distance from the current point to all points
        {
            int j = e[i];
            if(dist[j] > dist[ver] + w[i])
            {
                dist[j] = dist[ver] + w[i];
                heap.push({dist[j], j});
            }
        }
    }
    memcpy(f, dist, sizeof f);
}

int a_star()
{
    priority_queue<PIII, vector<PIII>, greater<PIII>> heap;
    heap.push({f[S], {0, S}}); //Sort by Valuation Function
    memset(st, 0, sizeof st);
    
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        
        int ver = t.second.second, distance = t.second.first;
        if(st[ver] >= K) continue;
        st[ver] ++;
        if(ver == T && st[ver] == K) return distance;
        
        for(int i = h[ver]; ~i; i = ne[i])
        {
            int j = e[i];
            if(st[j] < K)
                heap.push({distance + w[i] + f[j], {distance + w[i], j}});
        }
    }
    return -1;
}

int main()
{
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    memset(rh, -1, sizeof rh);
    while(m --)
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(h, a, b, c), add(rh, b, a, c);
    }
    scanf("%d%d%d", &S, &T, &K);
    if(S == T) K ++;
    
    dijkstra();
    
    printf("%d\n", a_star());
    
    return 0;
}

179.8 Digital

In a 3 *3 grid, the 8 digits of 1-8 and an "X" are exactly distributed in the 3 *3 grid.

For example:

1 2 3
X 4 6
7 5 8

In the course of the game, "X" can be exchanged with one of the four directions of top, bottom, left and right (if it exists).
Our goal is to change the grid into the following arrangement (called correct arrangement) by exchanging:

1 2 3
4 5 6
7 8 X

For example, the graphics in the example can be arranged correctly by allowing "X" to be exchanged successively with digits in the right, bottom and right directions.
The exchange process is as follows:

1 2 3   1 2 3   1 2 3   1 2 3
X 4 6   4 X 6   4 5 6   4 5 6
7 5 8   7 5 8   7 X 8   7 8 X

Record the action of "X" digital exchange with left and right directions as "u", "d", "l" and "r".
Now, give you an initial grid, and ask you to arrange it correctly with the least number of moves.

Input format
Input takes up one line, and the initial mesh of 3 *3 is depicted.
For example, if the initial grid is as follows:

1 2 3

x 4 6

7 5 8

The input is: 1 23 x 4 6 7 5 8

Output format
The output takes up one line and contains a string representing the complete action record in the correct arrangement.
If no solution exists, output "unsolvable".

Input sample:
2 3 4 1 5 x 7 6 8

sample output
ullddrurdllurdruldr

/*

Eight-digit problem has no solution if and only if the inverse logarithm is odd.

1~8 The sum of Manhattan distances for each number and final position

string, unordered_map<string, int>

*/

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>

using namespace std;

int f(string state)
{
    int res = 0;
    for(int i = 0; i < state.size(); i++)
        if(state[i] != 'x')
        {
            int t = state[i] - '1';
            res += abs(i / 3 - t / 3) + abs(i % 3 - t % 3);
        }
        return res;
}

string bfs(string start)
{
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //Upper right and lower left 
    char op[4] = {'u', 'r', 'd', 'l'};
    
    string end = "12345678x";
    unordered_map<string, int> dist; //Current Distance
    unordered_map<string, bool> st; //Has the current status been searched?
    unordered_map<string, pair<string, char>> prev;
    priority_queue<pair<int, string>, vector<pair<int, string>>, greater<pair<int, string>>> heap;
    
    heap.push({f(start), start});
    dist[start] = 0;
    
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        
        string state = t.second;
        
        if(state == end) break;
        
        if(st[state]) continue;
        st[state] = true;
        
        int step = dist[state];
        int x, y; //Find the current space position
        for(int i = 0; i < state.size(); i++)
            if(state[i] == 'x')
            {
                x = i / 3, y = i % 3;
                break;
            }
        string source = state;
        for(int i = 0; i < 4; i ++)
        {
            int a = x + dx[i], b = y + dy[i];
            if(a >= 0 && a < 3 && b >= 0 && b < 3)
            {
                swap(state[x * 3 + y], state[a * 3 + b]);
                if(!dist.count(state) || dist[state] > step + 1)
                {
                    dist[state] = step + 1;
                    prev[state] = {source, op[i]};
                    heap.push({dist[state] + f(state), state});
                }
                swap(state[x * 3 + y], state[a * 3 + b]);
            }
        }
    }
    string res;
    while(end != start)
    {
        res += prev[end].second;
        end = prev[end].first;
    }
    reverse(res.begin(), res.end());
    return res;
}

int main()
{
    string g, c, seq;
    while(cin >> c)
    {
        g += c;
        if(c != "x") seq += c;
    }
    
    int t = 0;
    for(int i = 0; i < seq.size(); i++)
        for(int j = i + 1; j < seq.size(); j ++)
            if(seq[i] > seq[j])
                t ++;
                
    if(t % 2) puts("unsolvable"); 
    else cout << bfs(g) << endl;
    
    return 0;
}

Posted by exally on Mon, 12 Aug 2019 05:22:04 -0700