codeforces 508D (无向图欧拉路径)

题目链接:点击这里

题意:给出n个单词(长度为3),求出一种头尾相连的方案。两个单词能连起来当且仅当前一个单词的后两位和后一个单词的前两位相同。

直接把每个单词看成边,前两位和后两位看成点,跑欧拉路径即可。需要一些优化把欧拉路径改成线性。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(linker, "/STACK:102400000,102400000")
#define Clear(x,y) memset (x,y,sizeof(x))
#define Close() ios::sync_with_stdio(0)
#define Open() freopen ("more.in", "r", stdin)
#define get_min(a,b) a = min (a, b)
#define get_max(a,b) a = max (a, b);
#define y0 yzz
#define y1 yzzz
#define fi first
#define se second
#define pii pair
#define pli pair
#define pll pair
#define pb push_back
#define pl c<<1
#define pr (c<<1)|1
#define lson tree[c].l,tree[c].mid,pl
#define rson tree[c].mid+1,tree[c].r,pr
#define mod 1000000007
typedef unsigned long long ull;
template <class T> inline T lowbit (T x) {return x&(-x);}
template <class T> inline T sqr (T x) {return x*x;}
template <class T>
inline bool scan (T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return 0; //EOF
    while (c != '-' && (c < '0' || c > '9') ) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
const double pi = 3.14159265358979323846264338327950288L;
using namespace std;
#define INF 1e17
#define maxn 100005
#define maxm 1000005
//-----------------morejarphone--------------------//

struct node {
    int v;
    string s;
    bool vis;
};
vector  g[maxn];
int from[maxn];
vector <string> ans;
map <string, int> gg;
int n, cnt;
int in[maxn], out[maxn];

void dfs (int u) { //cout << u << endl;
    int sz = g[u].size ();
    for (int i = from[u]; i < sz; i++) {
        if (!g[u][i].vis) {
            g[u][i].vis = 1;
            from[u] = i+1;
            dfs (g[u][i].v);
            ans.pb (g[u][i].s);
        }
        else break;
    }
}

char str[maxn];

int main () {
    //freopen ("more.in", "r", stdin);
    scanf ("%d", &n);
    gg.clear ();
    Clear (in, 0);
    Clear (out, 0);
    Clear (from, 0);
    int s = 0;
    cnt = 0;
    for (int i = 0; i < maxn; i++) g[i].clear ();
    for (int i = 0; i < n; i++) {
        scanf ("%s", str);
        string tmp = (string) str;
        string uu = ""; uu += tmp[0], uu += tmp[1];
        string vv = ""; vv += tmp[1], vv += tmp[2];
        int u, v;
        if (!gg.count (uu)) {
            gg[uu] = cnt++;
            u = gg[uu];
        }
        else u = gg[uu];
        if (!gg.count (vv)) {
            gg[vv] = cnt++;
            v = gg[vv];
        }
        else v = gg[vv];
        g[u].pb ((node) {v, tmp, 0});
        in[v]++; out[u]++;
        s = u;
    }
    int x = 0, y = 0;
    for (int i = 0; i < cnt; i++) {
        if (out[i]-in[i] == 1) {
            x++;
            s = i;
        }
        else if (in[i]-out[i] == 1) y++;
        else if (abs (in[i]-out[i]) > 1) {
            printf ("NO\n");
            return 0;
        }
    }
    if ((x^y) || x > 1 || y > 1) {
        printf ("NO\n");
        return 0;
    }
    ans.clear ();
    dfs (s);
    if (ans.size () != n) {
        printf ("NO\n");
        return 0;
    }
    printf ("YES\n");
    for (int i = n-1; i >= 0; i--) {
        if (i == n-1) printf ("%c%c%c", ans[i][0], ans[i][1], ans[i][2]);
        else printf ("%c", ans[i][2]);
    }
    puts ("");
    return 0;
}

你可能感兴趣的:(其他图论)