(beginer)DFS (dfs) UVA 10319 Manhattan

Problem H

Manhattan

Input: standard input

Output:  standard output

Time Limit: 1 second

Memory Limit: 32 MB

 

 

You are the mayor of a city with severe traffic problems. To deal with the situation, you have decided to make a new plan for the street grid. As it is impossible to make the streets wider, your approach is to make them one-way (only traffic in one direction is allowed on a street), thus creating a more efficient flow of traffic.

 

The streets in the city form an orthogonal grid - like on Manhattan avenues run in north-south-direction, while streets run in east-west-direction. Your mission is to make all the streets and avenues one-way, i.e. fix the direction in which traffic is allowed, while maintaining a short driving distance between some ordered pairs of locations. More specifically, a route in the city is defined by two street-avenue crossings, the start and goal location. On a one-way street grid, a route has a legal path if it is possible to drive from the start location to the goal location along the path passing streets and avenues in their prescribed direction only. A route does not define a specific path between the two locations - there may be many possible paths for each route. A legal path in a one-way street grid is considered simple if it requires at most one turn, i.e. a maximum of one street and one avenue need to be used for the path.

 

When traveling by car from one location to another, a simple path will be preferred over a non-simple one, since it is faster. However, as each street in the grid is one-way, there may always be routes for which no simple path exists. On your desk lies a list of important routes which you want to have simple paths after the re-design of the street grid.

 

Your task is to write a program that determines if it is possible to fix the directions of the one-way streets and avenues in such a way that each route in the list has at least one simple path.

 

(beginer)DFS (dfs) UVA 10319 Manhattan - 恶魔仁 - 恶魔仁

Input

On the first line of the input, there is a single integer n, telling how many city descriptions that follows. Each city description begins with a line containing three integers: the number of streets 0<S<=30 and avenues 0<A<=30 in the street grid, and the number of routes 0<m<=200 that should have at least one simple path. The next m lines define these routes, one on each line. Each route definition consists of four integers, s1, a1, s2, a2, where the start location of the route is at the crossing of street s1 and avenue a1, and the goal location is at the crossing of street s2 and avenue a2. Obviously, 0<s1, s2<=S and 0<a1, a2<=A.

 

Output

For each city, your program should output 'Yes' on a single line if it is possible to make the streets and avenues one-way, so that each route has at least one simple path. Otherwise the text 'No' should be printed on a line of its own.

 

Sample Input

3

6 6 2

1 1 6 6

6 6 1 1

7 7 4

1 1 1 6

6 1 6 6

6 6 1 1

4 3 5 1

9 8 6

2 2 4 4

4 5 3 2

3 4 2 2

3 2 4 4

4 5 2 2

2 1 3 4

 

Sample Output

Yes

No

No



题意:给出A行S列,(行列随便)然后要为这些行和列确定一个行走的方向,然后每一个起点到终点,是按照这个方向的,并且最多只有一次转弯。问能不能确定行列的方向。

思路:一条路线最多只有两种走法。如果他们同行或同列,很好讨论,如果他们不同行,不同列,那么一种是先横着走,再竖着走,另一种是先竖着走再横着走。我们用dira标记列的方向,dirs标记行的方向,然后就根据路线枚举所有的情况看能不能就行了。

代码:
#include<iostream>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 30+5;
int dirs[maxn] , dira[maxn];
int A , S , m;

struct Route
{
int s1 , a1;
int s2 , a2;
}route[205];

bool cmp(const Route & r1 , const Route & r2)
{
if (r1.s1==r2.s1) return r1.a1 < r2.a1;
return r1.s1 < r2.s1;
}

void init()
{
memset(dirs,0,sizeof(dirs));
memset(dira,0,sizeof(dira));
}

bool dfs(int cur)
{
if (cur==m) return true;
int s1 = route[cur].s1;
int a1 = route[cur].a1;
int s2 = route[cur].s2;
int a2 = route[cur].a2;
int s = a2 > a1 ? 1 : -1;
int a = s2 > s1 ? 1 : -1;
if (s1==s2)
{
if (a1==a2) 
{
if (dfs(cur+1)) return true;
return false;
}
if (dirs[s1]==-s) return false;
bool flags = dirs[s1]==0;
dirs[s1] = s;
if (dfs(cur+1)) return true;
if (flags) dirs[s1] = 0;
return false;
}
if (a1==a2)
{
if (dira[a1]==-a) return false;
bool flaga = dira[a1]==0;
dira[a1] = a;
if (dfs(cur+1)) return true;
if (flaga) dira[a1] = 0;
return false;
}
if (dirs[s1]==-s && dirs[s2]==-s) return false;
if (dira[a1]==-a && dira[a2]==-a) return false;
if (dira[a1]==0 || dira[a1]==a)
{
bool flaga = false , flags = false;
if (dira[a1]==0) flaga = true;
if (dirs[s2]==0 || dirs[s2]==s)
{
if (dirs[s2]==0) flags = true;
dira[a1] = a;
dirs[s2] = s;
if (dfs(cur+1)) return true;
if (flaga) dira[a1] = 0;
if (flags) dirs[s2] = 0;
}
if (dirs[s1]==0 || dirs[s1]==s)
{
bool flags = false , flaga = false;
if (dirs[s1]==0) flags = true;
if (dira[a2]==0 || dira[a2]==a)
{
if (dira[a2]==0) flags = true;
dira[a2] = a;
dirs[s1] = s;
if (dfs(cur+1)) return true;
if (flags) dirs[s1] = 0;
if (flaga) dira[a2] = 0;
}
}
return false;
}

void input()
{
for (int i = 0 ; i < m ; ++i)
scanf("%d%d%d%d",&route[i].s1,&route[i].a1,&route[i].s2,&route[i].a2);
sort(route,route+m,cmp);
}

void solve()
{
if (dfs(0)) printf("Yes\n");
else printf("No\n");
}

int main()
{
int T;
cin>>T;
while (T--)
{
scanf("%d%d%d",&A,&S,&m);
init();
input();
solve();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值