2021 RoboCom World Robot Developer Competition - Undergraduate Group (Preliminary) 7-3 Spectacular Upgrade (25 points)

Many games have a monster upgrade link, and players need to defeat a series of monsters to win achievements and badges. Here we consider a simple monster upgrade game, where the rules are given a map of N fortresses, with roads connecting them and a monster guarding each road. The monster itself has energy, and the weapons in its hands are valuable to defeat the monster.Energy equals the energy of the monster itself, and once the monster is defeated, the weapon is owned by the player - of course, the more valuable the captured weapon, the happier the player will be.

You have two tasks:

    1. Helps the player determine the most cost-effective airborne position, that is, to drop to a fortress on the map, so that the player starts from this airborne point and has the least energy required to attack the most difficult (that is, the most energy-consuming) fortress;
    1. Start from this landing point to help players find the most energy-efficient path to attack any of the fortresses they want to attack. If this path is not unique, choose the solution with the highest total value of the weapons captured along the way. The Title guarantees that the solution is unique.

Input format:

Enter the first line to give two positive integers N (< 1000) and M, where N is the total number of fortresses and M is the total number of monsters. For simplicity, we numbered the fortresses from 1 to N. Subsequently, line M gives information on line i only monsters in the following format:

B1 B2 Monster Energy Weapon Value

B1 and B2 are the castle numbers at both ends of the road guarded by monsters. The Title guarantees that only one monster is guarded between each pair of castles, and that the Monster Energy and weapon value are positive integers of no more than 100.

Next comes a positive integer K (< N) and the number of the K target fortresses the player wants to attack.

Output format:

First output the castle number B0 of the player's airborne in one line. If there is more than one possibility, output the one with the smallest number.

Then recommend the most energy-efficient attack path for each fortress the player wants to conquer. List the energy cost and the total value of the weapons captured along the way. Note that if the most energy-efficient path is not unique, choose the solution with the highest total value of the weapons captured along the way. The format is:

B0->Pass Fortress 1->...->B
 Total Energy Weapon Value

Input sample:

6 12
1 2 10 5
2 3 16 20
3 1 4 2
2 4 20 22
4 5 2 2
5 3 12 6
4 6 8 5
6 5 10 5
6 1 20 25
1 5 8 5
2 5 2 1
2 6 8 5
4
2 3 6 5

Output sample:

5
5->2
2 1
5->1->3
12 7
5->4->6
10 7
5
0 0

Ideas: Enumerate each point s, take s as the starting point to run the shortest path, and violence to find the most reasonable airborne location (Floyd). Run the shortest path again with the airborne location, maintain the double keyword shortest path and path information, and finally output the path according to the intention. The specific practice of this step can be referred to. Urban Rescue.

Time Complexity O(n^3).

 

 

#include<iostream> 
#include<cstring>
#include<unordered_map>
#include<vector>
#include<stack>
using namespace std;
const int INF = 0x3f3f3f3f, N = 1010, M = N*N;
struct Edge{
	int w=INF,x=0;//w Monster Value x Weapon Value 
}g[N][N];
int gg[N][N]; 
int d[N],wdis[N],xdis[N];//wdis is the shortest path to the airborne location, xdis is the weapon value 
int path[N];//Logging path information 
bool book[N];
int n,m;
int Floyd(){//Calculate airborne position 
	int num,minn = INF;
	for(int k = 1; k <= n; k++){
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= n; j++){
				if(gg[i][j] > gg[i][k] + gg[k][j]){
					gg[i][j] = gg[i][k] + gg[k][j];
				}
			}
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= n; j++){
			if(gg[i][j]!=INF) d[i] = max(d[i],gg[i][j]);
		}
		if(minn > d[i]){
			minn = d[i];
			num = i;
		}
	}
	return num; 
} 
void Djkstra(int idx){//Get Shortest Path Information 
    //Since only the closest point marker is selected each time, the shortest path information of the marked point cannot be changed
    //So you can record the path information from all points to the source point.
	wdis[idx] = 0;
	xdis[idx] = 0;
	for(int j = 1; j <= n; j++){
		int wminn = INF;
		int xmax = 0;
		int p = -1;
		for(int i = 1; i <= n; i++){
			if(!book[i] && (wminn > wdis[i] || (wminn == wdis[i] && xmax < xdis[i]))){
				wminn = wdis[i];
				xmax = xdis[i];
				p = i;
			}
		}
		book[p] = true;
		for(int i = 1; i <= n; i++){
			if(!book[i] && g[p][i].w != INF){
				if(wdis[i] > wdis[p] + g[p][i].w){
					wdis[i] = wdis[p] + g[p][i].w;
					xdis[i] = xdis[p] + g[p][i].x;
					path[i] = p;
				} else if((wdis[i] == wdis[p] + g[p][i].w) && (xdis[i] < xdis[p] + g[p][i].x)) {
					xdis[i] = xdis[p] + g[p][i].x;
					path[i] = p;
				}
			}
		}
	}
	
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	memset(wdis,0x3f,sizeof(wdis));
    memset(gg,0x3f,sizeof(gg));
	for(int i = 0; i < m; i++){
		int u,v,w,x;
		cin>>u>>v>>w>>x;
		g[u][v].w = g[v][u].w = w;//Djkstra needs
		g[u][v].x = g[v][u].x = x;
		gg[u][v] = gg[v][u] = w;//Floyd needs
	}
	int num = Floyd();
	Djkstra(num);//Get the shortest path information from all points to num points
	cout<<num<<'\n';
	int k;
	cin>>k;
	for(int i = 0; i < k; i++){
		if(i) cout<<'\n';
		int x;
		cin>>x;
		int ww = wdis[x],xx = xdis[x];
        //Processing the shortest path information path
		stack<int> pt;
		while(x!=num){
			pt.push(x);
			x = path[x];
		}
		cout<<num; 
		while(pt.size()){
			cout<<"->"<<pt.top();
			pt.pop();
		}
		cout<<'\n'<<ww<<' '<<xx;
	}
	return 0;
}

Tags: C++ Algorithm data structure

Posted on Thu, 14 Oct 2021 12:43:57 -0400 by Andy17