第一行,三個整數$T,M,N$。
接下來的$N$行,每行兩個整數$u_i,v_i$($i$從$1$開始編號)。容許$u_i=v_i$,也容許一樣的簡單詞屢次出現。html
第一行,一個字符串$YES$或$NO$,表示可否將這$N$個簡單詞組合成一個複雜詞。
若是能,則第二行輸出$N$個整數,第$i$個數$p_i$表示組成複雜詞的第$i$個簡單詞是輸入的編號爲$|p_i|$的簡單詞。注意,當$T=1$且使用編號爲$|p_i|$的簡單詞時交換了兩個字符的順序,則輸出編號的相反數,不然輸出編號。若是有多組解,輸出任意一組便可。c++
樣例輸入1:spa
1 3 2
2 3
1 3htm
樣例輸出1:blog
YES
2 -1字符串
樣例輸入2:get
2 5 5
2 3
2 5
3 4
1 2
4 2it
樣例輸出2:class
YES
4 1 3 5 2im
樣例$1$解釋:
若是用$a,b,c$分別表示字符$1,2,3$,則第一個簡單詞爲$bc$,第二個簡單詞爲$ac$,因此能夠交換第一個簡單詞的兩個字符,這樣就能夠組合成$acb$,因此輸出$2\ -1$。
數據範圍:
先來明確一下題意,對於$T=1$的狀況,能夠交換多個,而不是一個。
轉化題意,對於$T=1$的狀況,則是找無項圖的歐拉路;對於$T=2$的狀況,則是有向圖。
代碼實現上須要注意環的狀況,還須要反着輸出。
時間複雜度:$\Theta(N+M)$。
指望得分:$100$分。
實際得分:$100$分。
#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to,w;}e[400002];
int head[200001],cnt=1,tot,top,sum;
int T,M,N;
pair<int,int> a[200001];
int ans[200001],sta[200001],du[200001],in[200001],out[200001];
bool vis[400002],v[200001];
void add(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void dfs(int x)
{
vis[x]=1;
tot++;
for(int i=head[x];i;i=e[i].nxt)
if(!vis[e[i].to])dfs(e[i].to);
}
void dfs1(int x,int in)
{
for(int i=head[x];i;i=e[i].nxt)
{
if(vis[i])continue;
vis[i]=vis[i^1]=1;
head[x]=i;
dfs1(e[i].to,i);
i=head[x];
}
ans[++ans[0]]=e[in].w;
}
void dfs2(int x,int in)
{
if(!v[x]){v[x]=1;tot++;}
for(int i=head[x];i;i=e[i].nxt)
{
if(vis[i])continue;
head[x]=i;
vis[i]=1;dfs2(e[i].to,i);
i=head[x];
}
ans[++ans[0]]=e[in].w;
}
void work1()
{
for(int i=1;i<=N;i++)
{
scanf("%d%d",&a[i].first,&a[i].second);
if(!vis[a[i].first]){vis[a[i].first]=1;sum++;}
if(!vis[a[i].second]){vis[a[i].second]=1;sum++;}
add(a[i].first,a[i].second,i);
add(a[i].second,a[i].first,-i);
du[a[i].first]++;
du[a[i].second]++;
}
memset(vis,0,sizeof(vis));
dfs(a[1].first);
if(sum!=tot){puts("NO");exit(0);}
memset(vis,0,sizeof(vis));
for(int i=1;i<=N;i++)
{
if((du[a[i].first]&1)&&!vis[a[i].first]){sta[++top]=a[i].first;vis[a[i].first]=1;}
if((du[a[i].second]&1)&&!vis[a[i].second]){sta[++top]=a[i].second;vis[a[i].second]=1;}
}
memset(vis,0,sizeof(vis));
if(!top)dfs1(a[1].first,0);
else if(top==2)dfs1(sta[1],0);
else{puts("NO");exit(0);}
puts("YES");
for(int i=N;i;i--)printf("%d ",ans[i]);
}
void work2()
{
for(int i=1;i<=N;i++)
{
scanf("%d%d",&a[i].first,&a[i].second);
if(!vis[a[i].first]){vis[a[i].first]=1;sum++;}
if(!vis[a[i].second]){vis[a[i].second]=1;sum++;}
add(a[i].first,a[i].second,i);
out[a[i].first]++;
in[a[i].second]++;
}
memset(vis,0,sizeof(vis));
for(int i=1;i<=N;i++)
{
if(in[a[i].first]!=out[a[i].first])
{
if(in[a[i].first]!=out[a[i].first]+1&&in[a[i].first]!=out[a[i].first]-1){puts("NO");exit(0);}
if(!vis[a[i].first]){sta[++top]=a[i].first;vis[a[i].first]=1;}
}
if(in[a[i].second]!=out[a[i].second])
{
if(in[a[i].second]!=out[a[i].second]+1&&in[a[i].second]!=out[a[i].second]-1){puts("NO");exit(0);}
if(!vis[a[i].second]){sta[++top]=a[i].second;vis[a[i].second]=1;}
}
}
memset(vis,0,sizeof(vis));
if(!top)dfs2(a[1].first,0);
else if(top==2)
{
if(in[sta[1]]==out[sta[1]]-1)dfs2(sta[1],0);
if(in[sta[2]]==out[sta[2]]-1)dfs2(sta[2],0);
if(in[sta[1]]==out[sta[1]]-1&&in[sta[2]]==out[sta[2]]-1){puts("NO");exit(0);}
if(in[sta[1]]==out[sta[1]]+1&&in[sta[2]]==out[sta[2]]+1){puts("NO");exit(0);}
}
else{puts("NO");exit(0);}
if(tot!=sum){puts("NO");exit(0);}
puts("YES");
for(int i=N;i;i--)printf("%d ",ans[i]);
}
int main()
{
scanf("%d%d%d",&T,&M,&N);
if(T==1)work1();
else work2();
return 0;
}
rp++