LGOJ P1341 无序字母对

Posted kion

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LGOJ P1341 无序字母对相关的知识,希望对你有一定的参考价值。

很STL的题解

想法似乎跟别人不大一样,我不喜欢在char和int之间换来换去,所以选择了

map<char, vector<int> > G;

至于字典序,这个sort一下就ok。

其他的就是常规dfs,特别注意一定要用栈记录倒序输出。不然只有一半分数。

似乎有人问道:为什么要用栈记录倒序输出??
(dalao可以直接跳过本段)

我在这里简单而形象地解答一下:

举个例子:
技术图片

就这个图↑

显然,有且仅有两个点度数为奇,可以“一笔画”。我们在搜索的时候,如果这样写:

void dfs(char u)
{
    cout<<u;//先输出
    for (vector<int>::iterator it = G[u].begin(); it != G[u].end(); it++)
    {
        char now = *it;
        if (!vis[u][now])
        {
            vis[u][now] = 1;
            vis[now][u] = 1;
            dfs(now);
        }
    }
    
}

那就只有50分,因为对于上面所说的图该dfs的输出是:

CABDC

而正解是CCABD

这就要使用这种用栈记录倒序输出的方式了。

观察上面错误的输出,发现本该立即输出的C被滞后了,也就是说,这个C早该输出了。也就是说。我们应该保证一个点在输出之前确保之前的所有点已经输出过了。所以说输出的操作要放在最后,考虑到顺序问题应该倒序输出,堆个栈就行了。

下面是AC代码。
据不够强,偷个懒就不判断图的连通性了。


#include "stdafx.h"
#include <bits/stdc++.h>
using namespace std;
map<char, vector<int> > G;
map<char, int> cnt;
bool vis[200][200];
stack<char> sta;
int n, ed;


void dfs(char u)
{
   for (vector<int>::iterator it = G[u].begin(); it != G[u].end(); it++)
   {
       char now = *it;
       if (!vis[u][now])
       {
           vis[u][now] = 1;
           vis[now][u] = 1;
           dfs(now);
       }
   }
   sta.push(u);
}
bool cmp(char i, char j)
{
   return int(i) < int(j);
}
int main()
{
   cin >> n;
   bool flag = 0;
   char c = getchar(), q = 0;
   for (int i = 1; i <= n; i++)
   {
       string s;
       cin >> s;
       G[s[0]].push_back(s[1]);
       G[s[1]].push_back(s[0]);
       cnt[s[0]]++;
       cnt[s[1]]++;
   }
   int od = 0, x1 = 0, x2 = 0, c1 = 0, c2 = 0;
   for (map<char, int>::iterator it = cnt.begin(); it != cnt.end(); it++)
   {
       //保证一下字典序↓
       sort(G[it->first].begin(), G[it->first].end(), cmp);
       if (it->second % 2 != 0)
       {
           od++;//记录奇数点的个数
           //↓如果存在奇数点,那么这俩点就是路径的一始一末了
           //记录下来
           if (x1)x2 = it->second, c2 = it->first;
           else x1 = it->second, c1 = it->first;
       }
   }
   if (od != 2 && od != 0)
   {
       cout << "No Solution";
       return 0;
   }
   else
   {
       char minst = 'z';
       for (map<char, vector<int> >::iterator it = G.begin(); it != G.end(); it++)
       {
           if (minst > it->first)minst = it->first;
       }
       if (od == 2)
       {
           minst = min(c1, c2);
       }
       dfs(minst);//搜
   }
   while (!sta.empty())
   {
       cout << sta.top();
       sta.pop();
   }
   return 0;
}

以上是关于LGOJ P1341 无序字母对的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1341 无序字母对

[P1341]无序字母对 (欧拉回路)

洛谷P1341 无序字母对(欧拉回路)

p1341 无序字母对

P1341 无序字母对欧拉路径- Hierholzer模板

P1341 无序字母对(欧拉回路)