D. Okabe and City codeforces 最短路
2017-07-02 08:44
399 查看
D. Okabe and City
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Okabe likes to be able to walk through his city on a path lit by street lamps. That way, he doesn't get beaten up by schoolchildren.
Okabe's city is represented by a 2D grid of cells. Rows are numbered from
1 to n from top to bottom, and columns are numbered
1 to m from left to right. Exactly
k cells in the city are lit by a street lamp. It's guaranteed that the top-left cell is lit.
Okabe starts his walk from the top-left cell, and wants to reach the bottom-right cell. Of course, Okabe will only walk on lit cells, and he can only move to adjacent cells in the up, down, left, and right directions. However, Okabe can also temporarily
light all the cells in any single row or column at a time if he pays
1 coin, allowing him to walk through some cells not lit initially.
Note that Okabe can only light a single row or column at a time, and has to pay a coin every time he lights a new row or column. To change the row or column that is temporarily lit, he must stand at a cell that is lit initially. Also, once he removes his
temporary light from a row or column, all cells in that row/column not initially lit are now not lit.
Help Okabe find the minimum number of coins he needs to pay to complete his walk!
Input
The first line of input contains three space-separated integers
n, m, and
k (2 ≤ n, m, k ≤ 104).
Each of the next k lines contains two space-separated integers
ri and
ci (1 ≤ ri ≤ n,
1 ≤ ci ≤ m) — the row and the column of the
i-th lit cell.
It is guaranteed that all k lit cells are distinct. It is guaranteed that the top-left cell is lit.
Output
Print the minimum number of coins Okabe needs to pay to complete his walk, or
-1 if it's not possible.
Examples
Input
Output
Input
Output
Input
Output
Input
Output
Note
In the first sample test, Okabe can take the path
, paying only when moving
to (2, 3) an
4000d (4, 4).
In the fourth sample, Okabe can take the path
, paying when moving to
(1, 2), (3, 4), and
(5, 4).
这个题比较抽象,难就难在建图上。
感觉d题比e题还是难。
首先先说下点的选取。我们选取前k个点,以及n行中的每一行,m列中的每一列当做点。一共就是n+m+k个点。为什么要这么做呢?
因为从一个初始亮点可以选取任何一行或者一列去点亮,我们点亮的肯定是与亮点相邻的,要不没有任何意义。既然那一行(列)点亮了,我们是不是就可以到这一行(列)的任意一个位置而不用花费多余的金钱,这种性质不就是一个点吗?对于一个点亮点能够到达的边有6个,呈现田字形,所以一个亮点需要建立12条边(双向)。
然后直接前向星spfa就过了。
#include<bits/stdc++.h>
using namespace std;
int dir[4][2]= {0,1,0,-1,1,0,-1,0};
const int M=1e4+10;
int x[M],y[M];
int ans,k,n,m, ccnntt=0;
map<int,int>ycq[M];
struct aa
{
int u,v,w,next;
} edge[20*M];
int pre[3*M];
bool vis[3*M];
int dis[3*M];
void add(int u,int v,int w)
{
edge[ans].u=u;
edge[ans].v=v;
edge[ans].w=w;
edge[ans].next=pre[u];
pre[u]=ans++;
}
void dij()
{
dis[1]=0;
queue<int>ycqq;
ycqq.push(1);
vis[1]=0;
while(!ycqq.empty())
{
int u=ycqq.front();
ycqq.pop();
vis[u]=0;
for(int i=pre[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
int w=edge[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v])
{
vis[v]=1;
ycqq.push(v);
}
}
}
}
int minn=0x3f3f3f3f;
for(int i=1; i<=k; i++)
{
if(x[i]==n&&y[i]==m)
{
minn=min(minn,dis[i]);
}
else
{
if(abs(x[i]-n)<=1||abs(y[i]-m)<=1)
{
minn=min(minn,dis[i]+1);
}
}
}
if(minn==0x3f3f3f3f)
printf("%d\n",-1);
else
printf("%d\n",minn);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
ans=1;
for(int i=1; i<=(m+n+k); i++)
{
vis[i]=0;
dis[i]=0x3f3f3f3f;
pre[i]=-1;
}
for(int i=1; i<=k; i++)
{
scanf("%d%d",&x[i],&y[i]);
ycq[x[i]][y[i]]=i;
}
for(int i=1; i<=k; i++)
{
int xx=x[i],yy=y[i];
for(int j=0; j<4; j++)
{
int xxx=xx+dir[j][0];
int yyy=yy+dir[j][1];
if(ycq[xxx][yyy]>0)
{
add(i,ycq[xxx][yyy],0);
}
}
if(xx+1>=1&&xx+1<=n)
add(i,xx+1+k,1);
add(i,xx+0+k,1);
if(xx-1>=1&&xx-1<=n)
add(i,xx-1+k,1);
if(yy+1>=1&&yy+1<=m)
add(i,yy+1+n+k,1);
add(i,yy+0+n+k,1);
if(yy-1>=1&&yy-1<=m)
add(i,yy-1+n+k,1);
if(xx+1>=1&&xx+1<=n)
add(xx+1+k,i,0);
add(xx+0+k,i,0);
if(xx-1>=1&&xx-1<=n)
add(xx-1+k,i,0);
if(yy+1>=1&&yy+1<=m)
add(yy+1+n+k,i,0);
add(yy+0+n+k,i,0);
if(yy-1>=1&&yy-1<=m)
add(yy-1+n+k,i,0);
}
dij();
}
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Okabe likes to be able to walk through his city on a path lit by street lamps. That way, he doesn't get beaten up by schoolchildren.
Okabe's city is represented by a 2D grid of cells. Rows are numbered from
1 to n from top to bottom, and columns are numbered
1 to m from left to right. Exactly
k cells in the city are lit by a street lamp. It's guaranteed that the top-left cell is lit.
Okabe starts his walk from the top-left cell, and wants to reach the bottom-right cell. Of course, Okabe will only walk on lit cells, and he can only move to adjacent cells in the up, down, left, and right directions. However, Okabe can also temporarily
light all the cells in any single row or column at a time if he pays
1 coin, allowing him to walk through some cells not lit initially.
Note that Okabe can only light a single row or column at a time, and has to pay a coin every time he lights a new row or column. To change the row or column that is temporarily lit, he must stand at a cell that is lit initially. Also, once he removes his
temporary light from a row or column, all cells in that row/column not initially lit are now not lit.
Help Okabe find the minimum number of coins he needs to pay to complete his walk!
Input
The first line of input contains three space-separated integers
n, m, and
k (2 ≤ n, m, k ≤ 104).
Each of the next k lines contains two space-separated integers
ri and
ci (1 ≤ ri ≤ n,
1 ≤ ci ≤ m) — the row and the column of the
i-th lit cell.
It is guaranteed that all k lit cells are distinct. It is guaranteed that the top-left cell is lit.
Output
Print the minimum number of coins Okabe needs to pay to complete his walk, or
-1 if it's not possible.
Examples
Input
4 4 5 1 1 2 1 2 3 3 3 4 3
Output
2
Input
5 5 4
1 1
2 1
3 1
3 2
Output
-1
Input
2 2 4
1 1
1 22 1
2 2
Output
0
Input
5 5 4
1 1
2 23 34 4
Output
3
Note
In the first sample test, Okabe can take the path
, paying only when moving
to (2, 3) an
4000d (4, 4).
In the fourth sample, Okabe can take the path
, paying when moving to
(1, 2), (3, 4), and
(5, 4).
这个题比较抽象,难就难在建图上。
感觉d题比e题还是难。
首先先说下点的选取。我们选取前k个点,以及n行中的每一行,m列中的每一列当做点。一共就是n+m+k个点。为什么要这么做呢?
因为从一个初始亮点可以选取任何一行或者一列去点亮,我们点亮的肯定是与亮点相邻的,要不没有任何意义。既然那一行(列)点亮了,我们是不是就可以到这一行(列)的任意一个位置而不用花费多余的金钱,这种性质不就是一个点吗?对于一个点亮点能够到达的边有6个,呈现田字形,所以一个亮点需要建立12条边(双向)。
然后直接前向星spfa就过了。
#include<bits/stdc++.h>
using namespace std;
int dir[4][2]= {0,1,0,-1,1,0,-1,0};
const int M=1e4+10;
int x[M],y[M];
int ans,k,n,m, ccnntt=0;
map<int,int>ycq[M];
struct aa
{
int u,v,w,next;
} edge[20*M];
int pre[3*M];
bool vis[3*M];
int dis[3*M];
void add(int u,int v,int w)
{
edge[ans].u=u;
edge[ans].v=v;
edge[ans].w=w;
edge[ans].next=pre[u];
pre[u]=ans++;
}
void dij()
{
dis[1]=0;
queue<int>ycqq;
ycqq.push(1);
vis[1]=0;
while(!ycqq.empty())
{
int u=ycqq.front();
ycqq.pop();
vis[u]=0;
for(int i=pre[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
int w=edge[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v])
{
vis[v]=1;
ycqq.push(v);
}
}
}
}
int minn=0x3f3f3f3f;
for(int i=1; i<=k; i++)
{
if(x[i]==n&&y[i]==m)
{
minn=min(minn,dis[i]);
}
else
{
if(abs(x[i]-n)<=1||abs(y[i]-m)<=1)
{
minn=min(minn,dis[i]+1);
}
}
}
if(minn==0x3f3f3f3f)
printf("%d\n",-1);
else
printf("%d\n",minn);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
ans=1;
for(int i=1; i<=(m+n+k); i++)
{
vis[i]=0;
dis[i]=0x3f3f3f3f;
pre[i]=-1;
}
for(int i=1; i<=k; i++)
{
scanf("%d%d",&x[i],&y[i]);
ycq[x[i]][y[i]]=i;
}
for(int i=1; i<=k; i++)
{
int xx=x[i],yy=y[i];
for(int j=0; j<4; j++)
{
int xxx=xx+dir[j][0];
int yyy=yy+dir[j][1];
if(ycq[xxx][yyy]>0)
{
add(i,ycq[xxx][yyy],0);
}
}
if(xx+1>=1&&xx+1<=n)
add(i,xx+1+k,1);
add(i,xx+0+k,1);
if(xx-1>=1&&xx-1<=n)
add(i,xx-1+k,1);
if(yy+1>=1&&yy+1<=m)
add(i,yy+1+n+k,1);
add(i,yy+0+n+k,1);
if(yy-1>=1&&yy-1<=m)
add(i,yy-1+n+k,1);
if(xx+1>=1&&xx+1<=n)
add(xx+1+k,i,0);
add(xx+0+k,i,0);
if(xx-1>=1&&xx-1<=n)
add(xx-1+k,i,0);
if(yy+1>=1&&yy+1<=m)
add(yy+1+n+k,i,0);
add(yy+0+n+k,i,0);
if(yy-1>=1&&yy-1<=m)
add(yy-1+n+k,i,0);
}
dij();
}
相关文章推荐
- Codeforces Round #420 (Div. 2) D. Okabe and City (最短路)
- D - Okabe and City CodeForces - 821D
- Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)
- Jzzhu and Cities CodeForces - 449B (最短路 + 最短路的条数)
- Codeforces Round #420 (Div. 2) D. Okabe and City 最短路
- Codeforces#420 C. Okabe and Boxes
- Codeforces Round #420 (Div. 2) D. Okabe and City(最短路)
- codeforces B. Okabe and Banana Trees 结论题
- Okabe and Future Gadget Laboratory CodeForces - 821A
- Codeforces Yaroslav and Time(最短路)
- Codeforces Round #420 (Div. 2) E. Okabe and El Psy Kongroo DP+矩阵快速幂加速
- Codeforces Round #420 B. Okabe and Banana Trees
- Okabe and Banana Trees CodeForces - 821B
- Codeforces Round #Pi (Div. 2) E. President and Roads 最短路+桥
- Codeforces Round #Pi (Div. 2) E. President and Roads 最短路,桥
- Dima and Bacteria CodeForces - 400D [最短路+缩点] 好题~
- Codeforces Round #420 C. Okabe and Boxes
- Codeforces Round #Pi (Div. 2) E. President and Roads tarjan+最短路
- Okabe and Boxes CodeForces - 821C
- Okabe and El Psy Kongroo CodeForces - 821E【DP+矩阵快速幂】