poj1797 Heavy Transportation 【dijstra变形】 + HDU1010 Tempter of the Bone【DFS奇偶剪枝】

Background
Hugo Heavy is happy. After the breakdown of the Cargolifter project he can now expand business. But he needs a clever man who tells him whether there really is a way from the place his customer has build his giant steel crane to the place where it is needed on which all streets can carry the weight.
Fortunately he already has a plan of the city with all streets and bridges and all the allowed weights.Unfortunately he has no idea how to find the the maximum weight capacity in order to tell his customer how heavy the crane may become. But you surely know.

Problem
You are given the plan of the city, described by the streets (with weight limits) between the crossings, which are numbered from 1 to n. Your task is to find the maximum weight that can be transported from crossing 1 (Hugo's place) to crossing n (the customer's place). You may assume that there is at least one path. All streets can be travelled in both directions.
Input
The first line contains the number of scenarios (city plans). For each city the number n of street crossings (1 <= n <= 1000) and number m of streets are given on the first line. The following m lines contain triples of integers specifying start and end crossing of the street and the maximum allowed weight, which is positive and not larger than 1000000. There will be at most one street between each pair of crossings.
Output
The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the maximum allowed weight that Hugo can transport to the customer. Terminate the output for the scenario with a blank line.
Sample Input
1
3 3
1 2 3
1 3 4
2 3 5
Sample Output
Scenario #1:
4

题意:求所有路径最小权值的最大值。

思路:只要找到未扩展顶点路径的最大权值,取从源点直接到u的权值和从u到当前顶点权值中的较小值(即比较得到另一条路径的最小权值),如果从源点到当前顶点的权值小于较小值(当前路径的值如果小于另一条路径的最小权值),则更新。

去年博客~~

去年写过的题,今年再写,还是不行,仔细分析了一下,感觉自己去年还是没有真正的理解这道题。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f3f
const int maxn = 1010;
using namespace std; 
int vis[maxn][maxn];
int n,m,ans;
int dis[maxn],book[maxn]; 

int dijstra()
{
	int i,j,u,minn;
	for(i = 1; i <= n; i ++)
		dis[i] = vis[1][i];
	book[1] = 1;
	for(i = 1; i < n; i ++)
	{
		minn = -inf;
		for(j = 1; j  <= n; j ++)
		{
			if(dis[j] > minn&&!book[j])
			{
				u = j;
				minn = dis[j];
			}
		}
		book[u] = 1;
		for(j = 1; j <= n; j ++)
		{
			if((dis[j] < min(dis[u],vis[u][j]))&&!book[j])
				dis[j] = min(dis[u],vis[u][j]);
		}
	}
	return dis[n];
}

int main()
{
	int t,T=0;
	int i,j,x,y,w;
	//freopen("in.txt","r",stdin);
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(i = 0; i <= n; i ++)
			for(j = 0; j <= n; j ++)
					vis[i][j] = 0;
		memset(book,0,sizeof(book));
		for(i = 1; i <= m; i ++)
		{
			scanf("%d%d%d",&x,&y,&w);
			vis[x][y] = w;
			vis[y][x] = w;
		}
		printf("Scenario #%d:\n%d\n\n",++T,dijstra());
	}
	return 0;
}
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.

Input The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.

The input is terminated with three 0's. This test case is not to be processed.
Output For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO
YES

题意:奇偶剪枝的简单搜索题。

思路:剪枝两部分:剩下步数和当前点到终点的距离奇偶性一致;剩下步数+已走步数小于总步数。

结:自己居然没有想到是奇偶剪枝!!!


#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stdlib.h>
using namespace std;
const int maxn = 10;
char vis[maxn][maxn];
int book[maxn][maxn];
int n,m,t,sx,sy,ex,ey,flag;
int k[4][2]={0,1,0,-1,1,0,-1,0};
int OK(int x,int y)
{
	if(x<0||x>n-1||y<0||y>m-1)
		return 0;
	return 1;
}
void dfs(int x,int y,int step)
{
	int i,nx,ny;
	int time =  abs(x-ex)+abs(y-ey);
	if(time+step > t||time%2!=(t-step)%2)
		return ;
	if(x == ex&&y == ey&&step == t)
	{
		flag = 1;
		return ;
	}
	for(i = 0; i < 4; i ++)
	{
		nx = x + k[i][0];
		ny = y + k[i][1];
		if(OK(nx,ny)&&vis[nx][ny]!='X'&&!book[nx][ny])
		{
			book[nx][ny] = 1;
			dfs(nx,ny,step+1);
			book[nx][ny] = 0;
		}
		if(flag)
			break;
	}
	return;
}
int main()
{
	int i,j;
	while(scanf("%d%d%d",&n,&m,&t),n!=0||m!=0||t!=0)
	{
		memset(book,0,sizeof(book));
		for(i = 0;i < n; i ++)
		{
			scanf("%s",vis[i]);
			for(j = 0; j < m; j ++)
			{
				if(vis[i][j] == 'S')
				{
					book[i][j] = 1;
					sx = i;
					sy = j;
				}
				if(vis[i][j] == 'D')
				{
					ex = i;
					ey = j;
				}
			}
		}
		flag = 0;
		if(abs(sx-ex)+abs(sy-ey) > t )
		{
			printf("NO\n");
			continue;
		}
		dfs(sx,sy,0);
		if(flag)
			printf("YES\n");
		else
			printf("NO\n");
		
	}
	return 0;
}



猜你喜欢

转载自blog.csdn.net/hello_sheep/article/details/80317379