1. 程式人生 > >【洛谷P1341】無序字母對

【洛谷P1341】無序字母對

return 構造 c++ n+1 就是 sca 大小 sin 字母

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

題解:每個無需字母對可以看成無向圖中的一條邊。因此,題目中讓構造的就是一個歐拉路(路徑或回路均可),即:無向圖中的每條邊恰好經過一次的路徑。存在歐拉路的充要條件是:無向圖聯通,且每個頂點的度均為偶數有且僅有兩個頂點的度為奇數。

代碼如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=151;

bool G[maxn][maxn];
int n,f[maxn],deg[maxn];
char ch[5],stk[maxn<<2];

inline int find(int x){
    return x==f[x]?f[x]:f[x]=find(f[x]);
}

void read_and_parse(){
    scanf("%d",&n);
    for(int i=1;i<=150;i++)f[i]=i;
    for(int i=1;i<=n;i++){
        scanf("%s",ch+1);
        G[ch[1]][ch[2]]=G[ch[2]][ch[1]]=1;
        f[find(ch[1])]=find(ch[2]);
        ++deg[ch[1]],++deg[ch[2]];
    }
}

void dfs(int u){
    for(int i=1;i<=150;i++)if(G[u][i]){
        G[u][i]=G[i][u]=0;
        dfs(i);
    }
    stk[n--]=u;
}

void solve(){
    int cnt=0,st=0;
    for(int i=1;i<=150;i++)if(f[i]==i&&deg[i])++cnt;
    if(cnt!=1){puts("No Solution");return;}
    cnt=0;
    for(int i=1;i<=150;i++)
        if(deg[i]&1){
            ++cnt;
            if(!st)st=i;
        }
    if(!st){for(int i=1;i<=150;i++)if(deg[i]){st=i;break;}}
    if(cnt&&cnt!=2){puts("No Solution");return;}
    dfs(st);
    puts(stk);
}

int main(){
    read_and_parse();
    solve();
    return 0;
}

【洛谷P1341】無序字母對