1. 程式人生 > >洛谷 P1341 無序字母對 解題報告

洛谷 P1341 無序字母對 解題報告

lib .html turn clu 輸入輸出格式 pair init ace 1+n

P1341 無序字母對

題目描述

給定n個各不相同的無序字母對(區分大小寫,無序即字母對中的兩個字母可以位置顛倒)。請構造一個有n+1個字母的字符串使得每個字母對都在這個字符串中出現。

輸入輸出格式

輸入格式:

第一行輸入一個正整數n。

以下n行每行兩個字母,表示這兩個字母需要相鄰。

輸出格式:

輸出滿足要求的字符串。

如果沒有滿足要求的字符串,請輸出“No Solution”。

如果有多種方案,請輸出前面的字母的ASCII編碼盡可能小的(字典序最小)的方案

說明

【數據規模與約定】

不同的無序字母對個數有限,n的規模可以通過計算得到。


其實比較裸

先存儲,然後對邊排序。註意用前向星的話,從大的邊往小的邊加。然後直接跑歐拉路即可。

和這個題是差不多的。


Code:

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N=130;
const int M=10010;
int head[N],to[M],next[M],cnt=1;
void add(int u,int v)
{
    next[++cnt]=head[u];to[cnt]=v;head[u]=cnt;
    next[++cnt]=head[v];to[cnt]=u;head[v]=cnt;
}
pair <int ,int > edge[M];
int S=N,in[N],n;
void init()
{
    scanf("%d",&n);
    char u,v;
    for(int i=1;i<=n;i++)
    {
        scanf("\n");
        scanf("%c%c",&u,&v);
        if(u>v) swap(u,v);
        edge[i].first=u,edge[i].second=v;
        in[u]++;in[v]++;
        S=S>u?u:S;
    }
    int cnt0=0;
    for(int i=‘z‘;i>=‘A‘;i--)
        if(in[i]&1)
            S=i,cnt0++;
    if(cnt0>2)
    {
        printf("No Solution\n");
        exit(0);
    }
    sort(edge+1,edge+1+n);
    for(int i=n;i;i--)
        add(edge[i].first,edge[i].second);
}
int s[M],tot,vis[M];
void dfs(int now)
{
    for(int i=head[now];i;i=next[i])
    {
        if(!vis[i])
        {
            vis[i]=vis[i^1]=1;
            head[now]=next[i];
            dfs(to[i]);
        }
    }
    s[++tot]=now;
}
void work()
{
    dfs(S);
    for(int i=tot;i;i--)
        printf("%c",s[i]);
}
int main()
{
    init();
    work();
    return 0;
}

2018.7.4

洛谷 P1341 無序字母對 解題報告