2017蓝桥c语言真题,[蓝桥杯][2017年第八届真题]发现环 (C语言代码)------------C语言——菜鸟级...
解題思路:
并查集 找環(huán) 未成環(huán)之前 看作一個樹
用并查集找到環(huán) 兩點 找的同時 建立一個 并查集樹(自己瞎起的)找到兩點后
從兩個點分別回到并查集的根節(jié)點經過的點標記上 這兩個點單獨經過的點(交點處除外)都是環(huán)上點
原文? 歡迎訪問?我的博客
注意事項:
參考代碼:#include
#include
#define?N?1000002
typedef?long?long?ll;
ll?a[N][3],f[N],bj[N],jd[N];
//ll?BCJ(ll?s)//并查集找根和更新
//{??return?f[s]==0?s:f[s]=BCJ(f[s]);
//}
ll?BCJ(ll?s)
{
ll?tem?,tx=s;
while(f[tx]!=0)tx=f[tx];//并查集找根
while(s!=tx)//并查集更新
{?tem=f[s];
f[s]=tx;
s=tem;
}
return?tx;
}
void?BCJtree(ll?x1,ll?x2)//建立并查集樹
{
ll?tx=x2,next=x1,last=jd[x1];?//兩樹合并??父變子?子變父
while(next!=0)
{
jd[next]=tx;
tx=next;
next=last;
last=jd[next];
}
}
void?xzh(ll?x)//尋找環(huán)節(jié)點
{?ll?last,r=x;bj[x]+=1;
while(1)
{if(jd[x]==0||bj[x]==2)break;//到并查集根節(jié)點或有重復節(jié)點?跳出
last=jd[x];
bj[last]+=1;
x=last;
}
if(bj[x]==2)//?重復節(jié)點?消重和去多余節(jié)點
{?bj[x]=1;
while(jd[x]!=0)
{last=jd[x];
bj[last]=0;
x=last;
}
}
}
int?main()
{?ll?i,j,s1,s2,n,flag;
while(scanf("%lld",&n)!=EOF)
{??flag=0;
memset(f,0,sizeof(f));
memset(bj,0,sizeof(bj));
memset(jd,0,sizeof(jd));
for(i=1;i<=n;i++)
{?scanf("%lld%lld",&a[i][0],&a[i][1]);
if(!flag)
{
s1=BCJ(a[i][0]);
s2=BCJ(a[i][1]);
if(s1==s2)flag=i;//如果之前已經是同集合?這為環(huán)上兩點?標記
else
{
if(!f[a[i][0]])?f[s1]=s2,BCJtree(a[i][0],a[i][1]);//a[i][0]節(jié)點為單集合或作為根節(jié)點的集合
else??f[s2]=s1,BCJtree(a[i][1],a[i][0]);//?含a[i][1]的集合接在含a[i][0]的集合
}
}
}
xzh(a[flag][0]);//從?A節(jié)點開始走
xzh(a[flag][1]);//從?B節(jié)點開始走
for(i=1;i<=n;i++)
if(bj[i]==1)printf("%lld?",i);
printf("\n");
}
return?0;
}
總結
以上是生活随笔為你收集整理的2017蓝桥c语言真题,[蓝桥杯][2017年第八届真题]发现环 (C语言代码)------------C语言——菜鸟级...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux-如何添加路由表
- 下一篇: 香港恒生科技指数 什么是恒生科技指数