無序字母對

2022-05-05 18:12:06 字數 1815 閱讀 3217

傳送門

一道非常不錯的尤拉迴路(路徑)題……

我們已經知道怎麼求尤拉迴路(路徑)了,但是如果求字典序最小的呢?

求尤拉迴路是乙個深搜的過程……所以我們不如每次在向下乙個點深搜的時候,每次讓他先走那個字典序最小的節點,這樣我們就能保證字典序最小了。不過實際上這個用鄰接表實現會很麻煩。我的實現方法是,對於所有的邊,我們先把它拆成兩條有向邊,對於拆出來的邊賦予相同的id,之後我們把邊按照起始點和終點排個序(注意鄰接表的儲存方法,終點要倒著排序),然後跑尤拉路徑即可。

這道題中,因為我們要乙個長為n+1的字串滿足n個字元對都出現過且僅出現一次,那我們就相當於是把每個字元對看成一條邊,在這個圖上求尤拉路徑(迴路),所以一開始要先判定它能否有尤拉路徑(迴路),之後就正常dfs。

對於起始點的選擇有些神奇。我們不是每次都取最小的就行,因為如果要是求尤拉路徑的話,我們必須強制選編號最小的奇點開始,如果要是求尤拉迴路直接從最小的點開始即可。

這種題其實用鄰接矩陣方便……而且好像這個資料範圍鄰接矩陣和鄰接表跑的一樣快。

看一下**。

#include#include

#include

#include

#include

#include

#include

#define rep(i,a,n) for(int i = a;i <= n;i++)

#define per(i,n,a) for(int i = n;i >= a;i--)

#define enter putchar('\n')

using

namespace

std;

typedef

long

long

ll;const

int m = 20005

;const

int inf = 1000000009

;int

read()

while(ch >= '

0' && ch <= '9'

)

return ans *op;

}struct

edge

}e[m

<<1],q[m<<1

];int n,head[m],x,y,z,deg[m],ecnt = 1,minn = 100000,mpos = 100000

,cnt,ans[m],tot;

char s[10

];bool

vis[m];

void add(int x,int y,int

z)void dfs(int

x) }

}int

main()

sort(q+1,q+1+(n<<1

)); rep(i,

1,n<<1

)

//rep(i,1,100) printf("%d ",deg[i]);enter;

rep(i,1,100) if((deg[i]>>1)&1) tot++;

if(tot > 2

)

rep(i,

1,100) if(i < mpos && (deg[i]>>1) & 1) mpos =i;

if(mpos == 100000) ans[++cnt] = q[1].from,dfs(q[1].from

);

else ans[++cnt] =mpos,dfs(mpos);

if(cnt != n+1) printf("

no solution\n");

else

return0;

}

無序字母對

問題描述 給定n個各不相同的無序字母對 區分大小寫,無序即字母對中的兩個字母可以位置顛倒 請構造乙個有n 1個字母的字串使得每個字母對都在這個字串中出現。輸入格式 第一行輸入乙個正整數n。以下n行每行兩個字母,表示這兩個字母需要相鄰。輸出格式 輸出滿足要求的字串。如果沒有滿足要求的字串,請輸出 no...

無序字母對

題目描述 給定n個各不相同的無序字母對 區分大小寫,無序即字母對中的兩個字母可以位置顛倒 請構造乙個有n 1個字母的字串使得每個字母對都在這個字串中出現。輸入輸出格式 輸入格式 第一行輸入乙個正整數n。以下n行每行兩個字母,表示這兩個字母需要相鄰。輸出格式 輸出滿足要求的字串。如果沒有滿足要求的字串...

無序字母對

剛開始學尤拉迴路,因為不太理解導致 wa 了兩次。錯點 度數為奇數個的點數大於2時不存在尤拉路徑 是偶數個也不行 如果存在尤拉路徑而不是尤拉迴路時,不能隨便選乙個點當做起點,必須選度數為奇數的兩個點中的乙個。include include includeusing namespace std con...