Codeforces508 D. Tanya and Password(有向图欧拉路)

Posted live4m

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces508 D. Tanya and Password(有向图欧拉路)相关的知识,希望对你有一定的参考价值。

题意:

解法:

对于串xyz,将xy视为一个节点,yz视为一个节点,建立xy->yz的有向边.

然后判断是否存在欧拉路即可.

有向图欧拉路存在条件,满足其一则有解:
1.所有点的入度=出度,此时起点任选.
2.只有两个点的入度!=出度,且一个点入度=出度+1,另一个点入度+1=出度.此时起点为入度+1=出度的点.

同时,有解还需要保证只有一个连通块.

从起点开始dfs,回溯的时候将边入栈,栈的顺序就是遍历边的顺序,即方案.

code:

#include<bits/stdc++.h>
// #define MULTI_CASE
#define SYNC_OFF
#define PI pair<int,int>
#define ll long long
// #define int long long
using namespace std;
// const int mod=998244353;
const int mod=1e9+7;
const int maxm=2e5+5;
stack<PI>g[maxm];//用栈存图,因为每条边只需要走一次.
map<string,int>mp;int idx;
string s[maxm];
int mark[maxm];
int in[maxm];
int out[maxm];
stack<int>stk;
int n;
int get(string& s){
    if(!mp.count(s)){
        mp[s]=++idx;
    }
    return mp[s];
}
void dfs(int x){
    while(g[x].size()){
        PI t=g[x].top();g[x].pop();
        int v=t.first;
        int e=t.second;
        mark[e]=1;//标记访问过的边
        dfs(v);
        stk.push(e);
    }
}
void solve(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s[i];
        string ls=s[i].substr(0,2);
        string rs=s[i].substr(1,2);
        int l=get(ls),r=get(rs);
        g[l].push({r,i});
        out[l]++;in[r]++;
    }
    int st=1;
    int ma=0,mi=0;
    for(int i=1;i<=idx;i++){
        int dif=out[i]-in[i];
        if(!dif)continue;
        else if(dif==1)ma++,st=i;
        else if(dif==-1)mi++;
        else{
            cout<<"NO"<<endl;return ;
        }
    }
    if(ma!=mi||ma>1){
        cout<<"NO"<<endl;return ;
    }
    dfs(st);
    for(int i=1;i<=n;i++){
        if(!mark[i]){//无解,连通块不唯一
            cout<<"NO"<<endl;return ;
        }
    }
    //拿方案
    string ans;
    while(stk.size()){
        string x=s[stk.top()];stk.pop();
        if(ans.size()){
            ans+=x[2];
        }else{
            ans=x;
        }
    }
    //
    cout<<"YES"<<endl;
    cout<<ans<<endl;
}
void Main(){
    #ifdef MULTI_CASE
    int T;cin>>T;while(T--)
    #endif
    solve();
}
void Init(){
    #ifdef SYNC_OFF
    ios::sync_with_stdio(0);cin.tie(0);
    #endif
    #ifndef ONLINE_JUDGE
    freopen("../in.txt","r",stdin);
    freopen("../out.txt","w",stdout);
    #endif
}
signed main(){
    Init();
    Main();
    return 0;
}

以上是关于Codeforces508 D. Tanya and Password(有向图欧拉路)的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 659C Tanya and Toys

[2016-03-31][codeforces][659C][Tanya and Toys]

Codeforces-C. Tanya and Toys(水题)

Codeforces Round #705 (Div. 2) D. GCD of an Array

Codeforces Round #705 (Div. 2) D. GCD of an Array

Codeforces Round #244 (Div. 2) D. Match & Catch 后缀数组