|Vijos|图论最短路|P1406 古韵之鹊桥相会

https://vijos.org/p/1406

两个相邻点相同则权值为0,否则权值为1.

相邻点权值设为正无穷

然后在上面和下面加上一排数,上面的是起点,下面的是终点

最后Floyd,输出任意一个在起点和终点的距离(G[起点][终点])即可

#include
#include
#include
#include
#include
#define ms(i,j) memset(i, j, sizeof(i));
#define pa2(a,r,c) for (int j=1;j<=c;j++) printf("%d  ", j);putchar('\n');for (int i=1;i<=r;i++) {for (int j=1;j<=c;j++) if (a[i][j]>4000000) printf("x  "); else printf("%d  ", a[i][j]); putchar('\n');}
using namespace std;
int n,m;
int map[25][25];
int G[2500][2500];
int cnt = 0;
void f(int i, int j, int c)
{
	if (j-1>0&&map[i][j-1]==map[i][j])
	G[c][c-1]=0;
	else if (j-1>0&&map[i][j-1]!=map[i][j])
	G[c][c-1]=1;
	
	if (j+1<=m&&map[i][j+1]==map[i][j])
	G[c][c+1]=0;
	else if (j+1<=m&&map[i][j+1]!=map[i][j])
	G[c][c+1]=1;
	
	if (i-1>0&&c-m>0&&map[i-1][j]==map[i][j])
	G[c][c-m]=0;
	else if (i-1>0&&c-m>0&&map[i-1][j]!=map[i][j])
	G[c][c-m]=1;
	
	if (i+1<=n&&map[i+1][j]==map[i][j])
	G[c][c+m]=0;
	else if (i+1<=n&&map[i+1][j]!=map[i][j])
	G[c][c+m]=1;
}
int main () 
{ 
	ms(G,27);
	scanf("%d%d%*c", &n,&m);
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=m;j++)
		{
			map[i][j] = getchar();
		}	
		getchar();
	}
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=m;j++)
		{
			f(i,j, ++cnt);
		}
	}
	for (int i=cnt+1;i<=cnt+m;i++)
	{
		G[i-m][i]=G[i][i-m]=0; 
		if(i-1>cnt) G[i-1][i]=G[i][i-1]=0;
	} 
	cnt += m;
	for (int i=cnt+1;i<=cnt+m;i++)
	{
		G[i-cnt][i]=G[i][i-cnt]=0; 
		if(i-1>cnt) G[i-1][i]=G[i][i-1]=0;
	} 
	cnt += m;
	for (int k=1;k<=cnt;k++)
	for (int i=1;i<=cnt;i++)
	for (int j=1;j<=cnt;j++)
	if (k!=i&&k!=j&&i!=j)
	{
		G[i][j] = min(G[i][j], G[i][k]+G[k][j]);
	}
	printf("%d\n", G[cnt][cnt-m-1]+1);
	return 0;
}


你可能感兴趣的:(图论,-,最短路/差分约束,Vijos)