F - Construct a Palindrome (AtCoder Beginner Contest 197)

题目来源

https://atcoder.jp/contests/abc197/tasks/abc197_f

题意分析

  给一张图,每条边上面有一个字母,试着找出一条从起点出发到终点的一条最短路,使得按顺序每条边上的字母相连接是一个回文串,若不存在则输出 -1。

思路分析

  思维题。数据范围是1000量级,第一眼以为是dp,第二眼是双端bfs,卡了好久。
  解法是在我们建好这条路之后,我们往队列里面加入所有的长度为1的边以及长度为0的边(即以两个相同的点为两边的边),每次扩展的时候,原本长度为1的边往两边延伸扩展找边,直到两边找到字母相同的边时候,更新距离最小值,同时状态入队。
  于是可以发现的是,原本长度为1的边最后扩展出来的是奇数回文,长度为0的边最后扩展出来是偶数回文。

code

#include <bits/stdc++.h>

#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e3 + 7;
int head[maxn], nxt[maxn << 2], ver[maxn << 2], tot;
char c[maxn << 2];
int dis[maxn][maxn];

void adde(int u, int v, char ch){
    ++tot; ver[tot] = v; c[tot] = ch; nxt[tot] = head[u]; head[u] = tot;
}

int main(){
    int n, m; scanf("%d%d", &n, &m);
    for (int i=1; i<=m; i++){
        int u, v; char ch;
        scanf("%d%d %c", &u, &v, &ch);
        adde(u, v, ch);
        adde(v, u, ch);
    }

    queue <pair <int, int> > q;
    for (int i=1; i<=n; i++){
        for (int j=1; j<=n; j++) dis[i][j] = INF;
        dis[i][i] = 0;
    }
    for (int i=1; i<=n; i++) q.push({i, i});
    for (int i=1; i<=n; i++){
        for (int j=head[i]; j; j=nxt[j]){
            int v = ver[j];
            if (v <= i) continue;
            dis[i][v] = dis[v][i] = 1;
            q.push({i, v});
        }
    }
    int ans = 0;
    while (!q.empty()){
        int h1 = q.front().first, h2 = q.front().second;
        q.pop();
        for (int i=head[h1]; i; i=nxt[i]){
            int v1 = ver[i];
            for (int j=head[h2]; j; j=nxt[j]){
                int v2 = ver[j];
                if (c[i] == c[j] && v1 != v2){
                    if (dis[v1][v2] > dis[h1][h2] + 2){
                        dis[v1][v2] = dis[v2][v1] = dis[h1][h2] + 2;
                        q.push({v1, v2});
                    }
                }
            }
        }
    }
    if (dis[1][n] == INF) printf("-1\n");
    else printf("%d\n", dis[1][n]);
    return 0;
}
/*
3 3
1 2 a
2 3 a
1 3 a
*/

 

posted @ 2021-03-28 21:34  Rain_island  阅读(168)  评论(0编辑  收藏  举报
Title