D2欧拉路,拓扑排序,和差分约束

第一题:太鼓达人;
题意:给出k,求一个最长的M位01串,使其从每一个位置向后走k个得到 的M个k位01串互不相同(最后一个和第一个相邻,即是一个环) 。输出 字典序最小的答案 。2 ≤ k ≤ 11 。
结论+爆搜;
第二问我们将每个k二进制数看成一个点,在它后面加上0/1就能得 到两个新数,我们从这个数向两个新数连边,于是这就变成了求一个欧 拉回路的问题 。显然此题是存在欧拉回路的第一问答案为2的k次方 ,第二问暴力求欧拉回路即可 。
发现sjh的注释很详细,所以贿赂搞来了一个满满注释的代码,可以更好地理解;
#includeusing namespace std;const int maxn=2e3+50;templateinline void read(T &x){x=0;T f=1,ch=getchar();while (!isdigit(ch) && ch^'-') ch=getchar();if (ch=='-') f=-1, ch=getchar();while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();x*=f;}int n,t,ans[maxn];bool used[maxn];inline bool eular(int x,int k)//x是当前子串的十进制表示,k是当前查询次{if (used[x]) return 0;used[x]=1,ans[k]=x&1;//统计答案,&的规则是:有零则零,否则为一,返回末位数字if (k==t) return 1;//查询结束if (eular((x<<1)&(t-1),k+1)) return 1;if (eular((x<<1|1)&(t-1),k+1)) return 1;//将每个二进制数看成一个点,将他前面的数删去,并在它后面加上0/1就能得到两个新数used[x]=0;//回溯,以免影响之后的dfsreturn 0;}int main(){read(n);t=1<
View Code
【D2欧拉路,拓扑排序,和差分约束】意外发现邱神的代码,但没有写题解,所以只能看一下
#include using namespace std;int read(){int a;cin>>a;return a;}int i,k,m;struct node{int x,deep;}o[10010];bool Orz(node a,node b){return a.deep
View Code
第二题;

D2欧拉路,拓扑排序,和差分约束

文章插图
我们不必要知道每个单词的每个字母,只需要记录首字母和尾字母,所以转换成了一个判断欧拉回路的题目;
首先我们需要知道两个字母知否在一个同一个联通块上,我们可以用并差集来写,然后判断欧拉回路,方法不再陈述;
#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define MAX 26using namespace std;int out[MAX],in[MAX],flag[MAX],p[MAX],father[MAX];int Find(int x){if(father[x]!=x)father[x]=Find(father[x]);return father[x];}void Union(int a,int b) {int p=Find(a);int q=Find(b);if(p!=q)father[q]=p;}int main(){int i,k,count,a,b,nc,n;char str[1002];cin>>nc; while(nc--){for(i=0;i<26;i++)father[i]=i; memset(in,0,sizeof(in));memset(out,0,sizeof(out));memset(flag,0,sizeof(flag));cin>>n;for(i=1;i<=n;i++){cin>>str;a=str[0]-'a';b=str[strlen(str)-1]-'a';Union(a,b);in[b]++;out[a]++;flag[a]=flag[b]=1;}count=0;for(i=0;i<26;i++){father[i]=Find(i);if(flag[i] && father[i]==i)count++; }if(count>1){cout<<"The door cannot be opened."<