Aizu - 2200 AOJ floyd+dp

Title:

You are a hard-working programmer on an island country (ACM-ICPC Japan), and you have a good friend Litensan who is a postman in trouble: There are some towns on the island that are connected by water and dry roads, and you must walk by water. Use the boat, get off the boat at X and stop at X. And there is only one boat on the island, and the next time you want to take the waterway, you have to go back to X; there may be more than two waterways or dry roads between the two towns; the postman must deliver the courier in the order of the towns on the list (the towns may be repeated , and one-time processing is not allowed for duplicate towns, such as ABCB, B must go twice in order).

There are multiple sets of test data:

N M

x1 y1 t1 sl1

x2 y2 t2 sl2

xM yM tM slM

R

z1 z2 … zR

N (2 ≤ N ≤ 200) is the number of towns, and M (1 ≤ M ≤ 10000) is the combined number of road and water. From line 2 to line M + 1 is the description of the path. The path connects xi and yi. The path takes ti (1 ≤ ti ≤ 1000) time. When sli is L, it means it is a dry road, and when S is a waterway. There may be two or more paths connecting two towns, and the paths are both bidirectional.

The R in line M + 2 is the number of towns that Liteng needs to go to, and the z-sequence in line M + 3 is the number of towns that Liteng needs to go to.

In the initial state, Liteng and the ship are in the first town, and there must be a way to reach the town that needs to be visited.

When the test data is 0 0, it means termination.

Find the shortest time it takes for this person to complete the Z sequence

Source: https://blog.csdn.net/yopilipala/article/details/79654036

Idea: Due to the shortest time required to run the entire z-sequence, we must preprocess the shortest paths between all pairs of points on the land and water routes, so we can map the land routes and water routes separately, and run Floyd to find them.

After running the z sequence, R steps are required. The state of each step is related to the position of the previous step and the position of the ship, and has a recursive relationship, so we can perform DP. (The details are in the code). Finally, the shortest time when the boat stops at a certain point (point 1-n) when it reaches the Rth step is obtained. Choose the smallest among these n, which is the answer.

#include<bits/stdc++.h>
#define sd(x) scanf("%d",&x)
#define ss(x) scanf("%s",x)
#define sc(x) scanf("%c",&x)
#define sf(x) scanf("%f",&x)
#define slf(x) scanf("%lf",&x)
#define slld(x) scanf("%lld",&x)
#define me(x,b) memset(x,b,sizeof(x))
#define pd(d) printf("%d\n",d);
#define plld(d) printf("%lld\n",d);
#define eps 1.0E-8
// #define Reast1nPeace

typedef long long ll;

using namespace std;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x1f1f1f1f1f1f1f1f;

int n,m,r;
int land[210][210];
int water[210][210];
ll dp[1010][210];
int z [1010];

void floyd(){
	for(int i =1 ; i<=n ; i++){
		land[i][i] = water[i][i] = 0;
	}
	for(int k = 1 ; k<=n ; k++){
		for(int i = 1 ; i<=n ; i++){
			for(int j = 1 ; j<=n ; j++){
				if(land[i][j] > land[i][k]+land[k][j]){
					land[i][j] = land[i][k]+land[k][j];
				}
				if(water[i][j] > water[i][k]+water[k][j]){
					water[i][j] = water[i][k]+water[k][j];
				}
			}
		}
	}
}

int main(){
#ifdef Reast1nPeace
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	ios::sync_with_stdio(false);
	while(cin>>n>>m){
		if(n==0 && m==0) break;
		
		memset(land,INF,sizeof(land));
		memset(water,INF,sizeof(water));
		memset(dp,LINF,sizeof(dp));
		
		int x,y,t;string sl;
		for(int i = 1 ; i<=m ; i++){
			cin>>x>>y>>t>>sl;
			if(sl[0] == 'L'){
				land[x][y] = land[y][x] = min(land[x][y] , t);
			}
			else{
				water[x][y] = water[y][x] = min(water[x][y] , t);
			}
		}
		cin>>r;
		for(int i = 1 ; i<=r ; i++){
			cin>>z[i];
		}
		floyd();
		
		//dp[i][j] represents the shortest distance traveled when the ship stops at point j at the i-th step of the z array sequence		
		dp[1][z[1]] = 0;
		for(int i = 1 ; i<=r ; i++){ //i is the serial number of the z array
			for(int j = 1 ; j<=n ; j++){ //j means the boat stops at point j
				dp[i][j] = min(dp[i][j] , dp[i-1][j]+land[z[i-1]][z[i]]); //Only land
				for(int k = 1 ; k<=n ; k++){ //In the case of waterway, the boat will eventually have n positions to dock
					dp[i][k] = min(dp[i][k] , dp[i-1][j]+land[z[i-1]][j]+water[j][k]+land[k][z[i]]);
					//When you reach the i-th step, take the waterway, and the boat finally stops at point k,
					//From step i-1, first go to point j where the ship is, then sail to point k, and then go from land k to point i at step i.
				}
			}
		}
		
		ll minn = LINF;
		for(int i = 1 ; i<=n ; i++){
			if(minn > dp[r][i]){
				minn = dp[r][i];
			}
		}
		cout<<minn<<endl;
	}
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324785230&siteId=291194637