D. AB Graph from Codeforces Round #699 (Div. 2)

题意:有n个点,两两之间都有权为'a'或'b'的边,没有重边。你需要去找一条路径,使得路径组成的字符串是长度为(m)的回文串。

做法:由于只有a和b两种边权,所以:
①假设能找到一条边为(a,b,'a'or'b')和(b,a,'a'or'b'),则可以在这两点间反复横跳;
②如果没有这样一条边:
则需要找到下述3个点:(a,b,'a')(b,a,'b')(b,c,'a')(c,b,'b')
如果(m\%4==2):假设m==6,则从a点出发:a->b->a->b->c->b->c,构造的串是'abaaba'
如果(m\%4==0):假设m==8,则从b点出发:b->a->b->a->b->c->b->c->b,构造的串是'babaabab'

代码写得比较糟,不建议参考

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define fastio ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
double pi = acos(-1);
const double eps = 1e-9;
const int inf = 1e9 + 7;
const int maxn = 1e5 + 10;
ll mod = 1e9 + 7;

char c[1010][1010];
int in[2][1010], out[2][1010];

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, m;
		scanf("%d %d", &n, &m);
		for (int i = 1; i <= n; i++)in[0][i] = in[1][i] = out[0][i] = out[1][i] = 0;
		for (int i = 1; i <= n; i++)
		{
			getchar();
			for (int j = 1; j <= n; j++)
			{
				scanf("%c", &c[i][j]);
				if (c[i][j] == '*')continue;
				int flag = (c[i][j] == 'a');//边的类型
				out[flag][i]++;//flag型出边++
				in[flag][j]++;//flag型入边++
			}
		}
		int a = 0, b = 0, ok = 0;
		for (int i = 1; !a && i <= n; i++)
			for (int j = i + 1; j <= n; j++)
				if (c[i][j] == c[j][i])//可以直接来回走的类型
				{
					a = i, b = j;
					break;
				}
		if (a)
		{
			printf("YES
");
			printf("%d ",b);
			while (m--)
			{
				printf("%d ", a);
				if (m > 0)
					printf("%d ", b), m--;
			}
			printf("
");
			continue;
		}

		if (m & 1)//m为奇数随便选2个点来回走
		{
			printf("YES
");
			printf("%d ", 1);
			while (m--)
			{
				printf("%d ", 2);
				if (m > 0)
					printf("%d ", 1), m--;
			}
			printf("
");
		}
		else
		{
			//剩下的肯定出边是a则入边是b,否则ba,看能否找得到3个满足条件的点
			for (int i = 1; i <= n; i++)
			{
				if (in[0][i] >= 1 && out[1][i] >= 1 && in[1][i] >= 1 && out[0][i] >= 1)
				{
					ok = i;
					break;
				}
			}
			if (!ok)
			{
				printf("NO
");
				continue;
			}
			for (int i = 1; !a && i <= n; i++)
			{
				if (i == ok)continue;
				for (int j = i + 1; j <= n; j++)
				{
					if (j == ok)continue;
					if (c[i][ok] == c[ok][j])
					{
						a = i, b = j;
						break;
					}
				}
			}
			if (!a)
				printf("NO
");
			else
			{
				printf("YES
");
				if (m % 4 == 0)
				{
					printf("%d ", ok);
					for (int i = 1; i <= m / 4; i++)
						printf("%d %d ", a, ok);
					for (int i = 1; i <= m / 4; i++)
						printf("%d %d ", b, ok);
				}
				else
				{
					printf("%d ", a);
					for (int i = 1; i <= m / 4; i++)
						printf("%d %d ", ok, a);
					printf("%d %d ", ok, b);
					for (int i = 1; i <= m / 4; i++)
						printf("%d %d ", ok, b);
				}
				printf("
");
			}
		}
	}

	return 0;

}
原文地址:https://www.cnblogs.com/ruanbaiQAQ/p/14429360.html