hdu1269迷宫城堡(tanjar)
哇!
tanjar模板题,但是看懂还是花了一下午…
哎,萌新杀手,要是有个现在的我能给早上的我讲讲,不知道会省去多少时间
targan是干嘛的???
它是找环的
问:是否任意两个点之间都联通(整个图有且只有一个大环,环包括所有点)
tanjar是dfs搜索,用***时间戳***编号(dfn),并且对于每个点,(low)编号记下的是这个点和下一个点low的最小值,最小值初始化是编号,而后面的编号明显大于前面的,那么low永远等于dfn,直到…
直到它碰到它的信仰啊!
如果它碰到一个访问过的点,那么这个点的dfn是比它的low(dfn)小的,这几个点形成一个环,把这个环上所有点取出来,用这个环为所欲为,做自己想做的事,美滋滋;
targan可以找出所有环。。。嘛,不错的算法
#include <bits/stdc++.h>
using namespace std;
const int maxn=10010;
vector<int> vec[maxn];
int dfn[maxn],low[maxn],vis[maxn],blg[maxn],s[maxn];
//dfn时间戳,low成环的话环上的最小编号,vis判断是否成环,
//blg判断是否只有一个环且包括所有点,s-stack模拟栈
int n,m;int cnt,num,top;
void dfs(int u){
s[++top]=u;//入栈
vis[u]=1;int siz=vec[u].size();
low[u]=dfn[u]=++cnt;int i;//编号
for(i=0;i<siz;i++){
int v=vec[u][i];//取出有边点
if(!dfn[v]){ //如果没编号过,递归
dfs(v);
low[u]=min(low[u],low[v]); //如果找到了环,赋值环上最小编号
}else{
if(vis[v]){
low[u]=min(low[u],dfn[v]); //找到环
}
}
}int x;
if(low[u]==dfn[u]){ //如果自身low=自身dfn,那么是环的最小编号
//(只有一个节点的环也是环)
num++;
do{
x=s[top--];
vis[x]=0; //这个很重要可别忘了哦
blg[x]=num;
}while(x!=u); //对整个环,做自己想做的事,这里编号啦
}
}
void tarjan(){
int i;
for(i=1;i<=n;i++){
if(!dfn[i]){
dfs(i);
}
}
for(i=1;i<=n;i++){
if(blg[i]!=num){
cout<<"No"<<endl;
return;
}
}
cout<<"Yes"<<endl;
}
int main(){
int i,j,k;int a,b;
while(cin>>n>>m,n+m){
top=0;cnt=0;num=0;
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(vis,0,sizeof vis);
memset(blg,0,sizeof blg);
for(i=0;i<=n;i++)vec[i].clear();
for(i=1;i<=m;i++){
cin>>a>>b;vec[a].push_back(b);
}
tarjan();
}
}
跨年快乐!!!我爱你们!!!嘿嘿
努力,加油,我要成为最强的acmer(辣鸡快洗洗睡吧)