发现原来我并不会输出方案…
这题只要找第一个不相同的位置 pos
如果 ai,pos>ai+1,pos 那么 ai,pos 一定是大写, ai+1,pos 一定是小写
如果 ai,pos<ai+1,pos 那么如果 ai,pos 是大写, ai+1,pos 也要大写, ai+1,pos 是小写,那么 ai,pos 也要是小写
就这样建边跑2-SAT就好了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <assert.h>
#include <cstring>
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
const int N=500010,P=1e9+7;
int n,m,cnt;
int a[N],b[N],G[N],bg[N],sm[N];
struct edge{
int t,nx;
}E[N*20];
inline void addedge(int x,int y){
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
//cout<<x<<' '<<y<<endl;
}
int bel[N],stk[N],vis[N],low[N],dfn[N],top,tms,g;
void tarjan(int x){
vis[x]=1;
dfn[x]=low[x]=++tms;
stk[++top]=x;
for(int i=G[x];i;i=E[i].nx){
if(!vis[E[i].t]) tarjan(E[i].t);
if(vis[E[i].t]==1) low[x]=min(low[x],low[E[i].t]);
}
if(low[x]==dfn[x]){
++g; int k;
do{
k=stk[top--];
bel[k]=g;
vis[k]=2;
}while(top && k!=x);
}
}
int Q[N],l,r;
int main(){
scanf("%d%d",&n,&m);
scanf("%d",a);
for(int i=1;i<=*a;i++) scanf("%d",&a[i]);
scanf("%d",b);
for(int i=1;i<=*b;i++) scanf("%d",&b[i]);
int cur;
for(cur=1;cur<=*a && cur<=*b;cur++) if(a[cur]!=b[cur]) break;
if(cur<=*a && cur<=*b){
if(a[cur]>b[cur]) addedge(a[cur]<<1,a[cur]<<1|1),addedge(b[cur]<<1|1,b[cur]<<1),bg[a[cur]]=1,sm[b[cur]]=1;
else addedge(b[cur]<<1|1,a[cur]<<1|1),addedge(a[cur]<<1,b[cur]<<1);
}
if(*a!=*b && cur>*b) return puts("No"),0;
int *A=b,*B=a;
for(int i=1;i<n-1;i++){
scanf("%d",B);
for(int j=1;j<=*B;j++) scanf("%d",&B[j]);
int cur;
for(cur=1;cur<=*A && cur<=*B;cur++)
if(A[cur]!=B[cur]) break;
if(cur<=*A && cur<=*B){
if(A[cur]>B[cur]) addedge(A[cur]<<1,A[cur]<<1|1),addedge(B[cur]<<1|1,B[cur]<<1),bg[A[cur]]=1,sm[B[cur]]=1;
else addedge(B[cur]<<1|1,A[cur]<<1|1),addedge(A[cur]<<1,B[cur]<<1);
}
if(*A!=*B && cur>*B) return puts("No"),0;
swap(A,B);
}
for(int i=2;i<=(m<<1|1);i++)
if(!vis[i]) tarjan(i);
for(int i=1;i<=m;i++)
if(bel[i<<1]==bel[i<<1|1]) return puts("No"),0;
puts("Yes");
vector<int> ans;
for(int i=1;i<=m;i++){
if(bel[i<<1|1]<bel[i<<1]) ans.push_back(i);
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++) printf("%d ",ans[i]);
return 0;
}