kuangbin帶你飛:點擊進入新世界
總結:
本人算是初學者中的初學者,歡迎交流~
由於是個人總結向,所以有點精簡,但是坑點和結果是怎麼算出來的都會提及,當然如果有什麼疑問可以留言或者私信交流。
後續會整理一下tarjan相關模板。
文章目錄
1.Network of Schools /強連通分量+縮點
原題鏈接:傳送門
思路:
- 算是學完tarjan的第一發吧。
- tarjan求強連通分量,然後縮點,查看有幾個強連通圖,查看縮點後的DAG入度爲0和出度爲0的多少,選取其中最大值。
- 新的一條線爲入度爲0的連到出度爲0,所以取max 。
代碼如下:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define v30 (1<<30)-1
#define all(x) (x).begin(),(x).end()
#define maxs *s.rbegin()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mid ((a[k].r+a[k].l)>>1)
#define lson k<<1,l,mid
#define rson k<<1|1,mid+1,r
#define kl k<<1
#define kr k<<1|1
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("Yes") ;}
void put2(){ puts("No") ;}
void put3(){ puts("-1"); }
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
using namespace std;
const int manx=5e5+5;
const int mamx=5e5+5;
// dfn 時間戳 low回溯 vis 是否在棧中
// ans爲強連通分量裏面的點數
// out 出度 in 入度
// s棧 col強連通
// cnt 強連通分量計數
ll head[manx],dfn[manx],low[manx],ans[manx];
ll out[manx],col[manx],s[manx],in[manx];
bool vis[manx];
ll k=0,ti=0,top=0,cnt=0,n,m;
struct node {
ll v,next;
}e[mamx*2];
void add(ll u,ll v){
e[++k].v=v;
e[k].next=head[u];
head[u]=k;
}
void tarjan(ll x){
dfn[x]=low[x]=++ti,vis[x]=1,s[++top]=x;
for(int i=head[x];i;i=e[i].next){
ll u=e[i].v;
if(!dfn[u]) tarjan(u),low[x]=min(low[x],low[u]);
else if(vis[u]) low[x]=min(low[x],dfn[u]);
}
if(low[x]==dfn[x]){
++cnt;
ll y;
do{
y=s[top--],vis[y]=0;
col[y]=cnt;
ans[cnt]++;
}while(x!=y);
}
}
int main()
{
n=read();
for(int i=1;i<=n;i++){
ll v=read();
while(v){
add(i,v);
v=read();
}
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=e[j].next)
if(col[e[j].v]!=col[i])
++out[col[i]],++in[col[e[j].v]];
ll res1=0,res2=0;
for(int i=1;i<=cnt;i++){
if(!out[i])
res1++;
if(!in[i])
res2++;
}
// cout<<res1<<" "<<res2<<endl;
if(cnt==1) cout<<1<<endl<<0<<endl;
else cout<<res2<<endl<<max(res1,res2)<<endl;
return 0;
}
2.Network /割點模板題
原題鏈接:傳送門
思路:
- tarjan求割點模板題。
- 割點的條件有:
- 對於根節點:有2棵即以上的子樹
- 對於非根節點:low[v]>=dfn[u]
代碼如下:
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define v30 (1<<30)-1
#define all(x) (x).begin(),(x).end()
#define maxs *s.rbegin()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
using namespace std;
const int manx=5e5+5;
const int mamx=5e5+5;
ll head[manx],dfn[manx],low[manx];
bool vis[manx];
ll n,m,id,cnt,tot,k;
struct node {
ll v,next;
}e[mamx*2];
void init(){
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
id=cnt=tot=k=0;
}
void add(ll u,ll v){
e[++k].v=v;
e[k].next=head[u];
head[u]=k;
}
void tarjan(ll u,ll f){
dfn[u]=low[u]=++id;
int child=0;
for(int i=head[u];i;i=e[i].next){
ll v=e[i].v;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=f) vis[u]=1;
if(u==f) child++;
}
low[u]=min(low[u],dfn[v]);
}
if(child>=2&&u==f) vis[u]=1; //如果是根節點,並且有一個以上的子節點
}
int main()
{
int n,u,v;
char c;
while(scanf("%d",&n),n){
init();
while(scanf("%d",&u),u){
while(scanf("%d%c",&v,&c)){
add(u,v),add(v,u);
if(c=='\n') break;
}
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i,i);
for(int i=1;i<=n;i++)
if(vis[i])
tot++;
cout<<tot<<endl;
}
return 0;
}
3.Critical Links /橋的模板題
原題鏈接:傳送門
思路:
- Tarjan求橋的模板題。
- 這題有要求按字典序輸出,所以可以用vector + pair 來儲存。
- pair的排序是先排序first後排序second。
代碼如下:
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define v30 (1<<30)-1
#define all(x) (x).begin(),(x).end()
#define maxs *s.rbegin()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
using namespace std;
const int manx=1e3+5;
const int mamx=2e6+5;
/*
8
0 (1) 1
1 (3) 2 0 3
2 (2) 1 3
3 (3) 1 2 4
4 (1) 3
7 (1) 6
6 (1) 7
5 (0)
*/
ll head[manx],dfn[manx],low[manx];
ll bridge;
ll n,m,id,cnt,tot,k=1;
struct node {
ll v,next;
bool cut;
}a[mamx*2];
void init(){
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
id=cnt=tot=k=bridge=0;
}
void add(ll u,ll v){
a[k].v=v;
a[k].next=head[u];
a[k].cut=false;
head[u]=k++;
}
void tarjan(ll u,ll pre){
dfn[u]=low[u]=++id;
for(int i=head[u];i;i=a[i].next){
ll v=a[i].v;
if(v==pre) continue;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]) a[i].cut=a[i^1].cut=1,bridge++;
}
else low[u]=min(low[u],dfn[v]);
}
}
int main()
{
int n,m,u,v;
char c;
while(scanf("%d",&n)!=EOF){
init();
for(int i=1;i<=n;i++){
scanf("%d%c%c%d%c",&u,&c,&c,&m,&c);
for(int j=1;j<=m;j++) v=read(),add(u,v),add(v,u);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i,i);
vector<pair<ll,ll> >ans;
for(int i=0;i<k;i+=2){
if(a[i].cut)
if(a[i].v<a[i^1].v) ans.pb(mp(a[i].v,a[i^1].v));
else ans.pb(mp(a[i^1].v,a[i].v));
}
sort(all(ans));
cout<<ans.size()<<" critical links"<<endl;
for(int i=0;i<ans.size();i++){
cout<<ans[i].fi<<" - "<<ans[i].se<<endl;
}
cout<<endl;
}
return 0;
}
4.Network /橋+LCA
原題鏈接:傳送門
思路:
- Tarjan求橋,然後利用lca思想,不斷地更新答案。
- 因爲當(u,v)相連時,u-v-lca(u,v) 構成了一個環,在這個環上的橋的屬性取消。
代碼如下:
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define v30 (1<<30)-1
#define all(x) (x).begin(),(x).end()
#define maxs *s.rbegin()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
using namespace std;
const int manx=1e5+5;
const int mamx=2e6+5;
ll head[manx],dfn[manx],low[manx];
ll bridge[manx],f[manx],d[manx],ans;
ll n,m,id,cnt,tot,k;
struct node {
ll v,next;
}a[mamx*2];
void init(){
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(f,0,sizeof(f));
memset(bridge,0,sizeof(bridge));
memset(d,0,sizeof(d));
id=cnt=tot=k=ans=0;
}
void add(ll u,ll v){
a[k].v=v;
a[k].next=head[u];
head[u]=k++;
}
void tarjan(ll u,ll pre){
dfn[u]=low[u]=++id;
for(int i=head[u];i;i=a[i].next){
ll v=a[i].v;
if(v==pre) continue;
if(!dfn[v]){
f[v]=u;
d[v]=d[u]+1;
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]) bridge[v]=1,ans++;
}
else low[u]=min(low[u],dfn[v]);
}
}
void check(int u,int v){
while(d[u]>d[v]){
if(bridge[u]) ans--,bridge[u]=0;
u=f[u];
}
while(d[v]>d[u]){
if(bridge[v]) ans--,bridge[v]=0;
v=f[v];
}
while(u!=v){
if(bridge[v]) ans--,bridge[v]=0;
if(bridge[u]) ans--,bridge[u]=0;
u=f[u],v=f[v];
}
}
int main()
{
int n,m,u,v,t=1;
while(scanf("%d%d",&n,&m)!=EOF){
if(!n&&!m) break;
init();
for(int i=1;i<=m;i++){
u=read(),v=read();
add(u,v),add(v,u);
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
if(!dfn[i]) tarjan(i,i);
printf("Case %d:\n",t++);
for(int i=1;i<=m;i++){
u=read(),v=read();
check(u,v);
printf("%lld\n",ans);
}
printf("\n");
}
return 0;
}
5.Redundant Paths /雙連通分量
原題鏈接:傳送門
思路:
- tarjan算法求雙連通分量(其實跟強連通分量是一樣的)。
- 縮點形成一棵樹,求這顆樹有多少個葉子節點即可。
- 答案就是(葉子節點+1)/2。注意重邊處理。
- 所有度爲1的葉子結點兩兩相連 。
代碼如下:
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define v30 (1<<30)-1
#define all(x) (x).begin(),(x).end()
#define maxs *s.rbegin()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
using namespace std;
const int manx=1e5+5;
const int mamx=2e6+5;
ll low[manx],dfn[manx],ssc[manx],s[manx],vis[manx],head[manx];
ll k,cnt,tot,top,id;
ll x[manx],y[manx],d[manx];
struct node{
ll v,next;
bool cut;
}a[mamx];
void init(){
memset(vis,0,sizeof(vis));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(ssc,0,sizeof(ssc));
memset(head,-1,sizeof(head));
memset(s,0,sizeof(s));
memset(d,0,sizeof(d));
top=tot=cnt=k=id=0;
}
void add(int u,int v){
a[k].next=head[u];
a[k].v=v;
a[k].cut=false;
head[u]=k++;
}
void tarjan(int u,int pre){
low[u]=dfn[u]=++id,vis[u]=1,s[++top]=u;
for(int i=head[u];i!=-1;i=a[i].next){
int v=a[i].v;
if(v==pre) continue;
if(!dfn[v]){
tarjan(v,u),low[u]=min(low[u],low[v]);
if(dfn[u]<low[v]) a[i].cut=a[i^1].cut=1;
}
else if(vis[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
int v;
cnt++;
do{
v=s[top--],vis[v]=0;
ssc[v]=cnt;
}while(v!=u);
}
}
int main()
{
int n,m,u,v;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=1;i<=m;i++){
x[i]=read(),y[i]=read();
u=x[i],v=y[i];
add(u,v),add(v,u);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i,i);
for(int i=0;i<k;i++){
if(a[i].cut)
d[ssc[a[i].v]]++;
}
ll ans=0;
for(int i=1;i<=cnt;i++)
if(d[i]==1) ans++;
// cout<<ans<<endl;
printf("%lld\n",(ans+1)/2);
}
return 0;
}
6.Strongly connected /強通塊+縮點
原題鏈接:傳送門
思路:
- 找出強聯通塊,計算每個連通塊內的個數。
- 將點數最少的那個連通塊單獨拿出來作爲連通分量a,其餘的連通塊合併成一個連通分量。
- 要使其爲強連通圖,那邊數爲n*(n-1)-m-a*(n-a)
- 原本的邊數爲m 能添加多少邊 取決於 -a*n+a^2
- 由於n比a大,所以a越小能添加的邊數越多,所以取縮點後的連通塊裏面塊數最小的爲a 。
代碼如下:
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define v30 (1<<30)-1
#define all(x) (x).begin(),(x).end()
#define maxs *s.rbegin()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
using namespace std;
const int manx=1e5+5;
const int mamx=2e6+5;
ll low[manx],dfn[manx],ssc[manx],s[manx],vis[manx],head[manx];
ll x[manx],y[manx],in[manx],out[manx],cnts[manx];
ll k,cnt,tot,top,id;
struct node{
ll v,next;
}a[mamx];
void init(){
memset(vis,0,sizeof(vis));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(ssc,0,sizeof(ssc));
memset(head,-1,sizeof(head));
memset(cnts,0,sizeof(cnts));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(s,0,sizeof(s));
top=tot=cnt=k=id=0;
}
void add(int u,int v){
a[k].next=head[u];
a[k].v=v;
head[u]=k++;
}
void tarjan(int u){
low[u]=dfn[u]=++id,vis[u]=1,s[++top]=u;
for(int i=head[u];i!=-1;i=a[i].next){
int v=a[i].v;
if(!dfn[v])
tarjan(v),low[u]=min(low[u],low[v]);
else if(vis[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
int v;
cnt++;
do{
v=s[top--],vis[v]=0;
ssc[v]=cnt;
cnts[cnt]++;
}while(v!=u);
}
}
int main()
{
ll p=read(),u,v,t=1;
while(p--){
ll n=read(),m=read();
init();
for(int i=1;i<=m;i++){
u=x[i]=read(),v=y[i]=read();
add(u,v);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
if(cnt==1){
printf("Case %d: -1\n",t++);
continue;
}
for(int i=1;i<=m;i++){
u=ssc[x[i]],v=ssc[y[i]];
if(u!=v)
out[u]++,in[v]++;
}
ll ans=n*(n-1)-m,mi=n;
for(int i=1;i<=cnt;i++)
if(!in[i]||!out[i])
mi=min(mi,cnts[i]);
printf("Case %d: ",t++);
cout<<ans-mi*(n-mi)<<endl;
}
return 0;
}
7.Caocao’s Bridges /橋
原題鏈接:傳送門
思路:
- 注意重邊處理。
- 守衛爲0時,也需要派一個人;
- 如果原本圖不連通,就不需要派人。
- 然後直接輸出橋的最小邊權就可以了。
代碼如下:
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<iostream>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define v30 (1<<30)-1
#define all(x) (x).begin(),(x).end()
#define maxs *s.rbegin()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
using namespace std;
const int manx=1e3+5;
const int mamx=2e6+5;
ll low[manx],dfn[manx],head[manx];
ll k,cnt,top,id,bridge;
struct node{
ll v,next,w;
}a[mamx];
void init(){
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(head,-1,sizeof(head));
top=cnt=k=id=0;
bridge=inf;
}
void add(ll u,ll v,ll w){
a[k].next=head[u];
a[k].v=v;
a[k].w=w;
head[u]=k++;
}
void tarjan(ll u,ll pre){
low[u]=dfn[u]=++id;
for(int i=head[u];i!=-1;i=a[i].next){
ll v=a[i].v;
if(i==(pre^1)) continue;
if(!dfn[v]){
tarjan(v,i),low[u]=min(low[u],low[v]);
if(dfn[u]<low[v]) bridge=min(bridge,a[i].w);
}
else low[u]=min(low[u],dfn[v]);
}
}
int main()
{
ll n,m,u,v,w;
while(scanf("%lld%lld",&n,&m),n+m){
init();
for(int i=1;i<=m;i++){
u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
}
ll tarjans=0;
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i,-1),tarjans++;
if(tarjans>1){
printf("0\n");
continue;
}
if(bridge==inf) bridge=-1;
else if(bridge==0) bridge=1;
printf("%lld\n",bridge);
}
return 0;
}