hdu 1269
强连通分量题,用tarjin算法;
这是一道很简单的tarjin算法题,基本上就是套模板;
贴代码:
#include<cstdio> #include<vector> #include<cstring> #include<stack> #define maxn 10005 using namespace std; vector<int>ve[maxn]; int dfn[maxn],low[maxn],ans,n,m,nncount; bool instack[maxn],vis[maxn]; stack<int>q; void tarjin(int x) { dfn[x]=low[x]=++nncount; vis[x]=1,instack[x]=1; q.push(x); int l=ve[x].size(); for(int i=0; i<l; i++) { int v=ve[x][i]; if(!vis[v]) { tarjin(v); low[x]=min(low[x],low[v]); } else if(instack[v]) low[x]=min(low[x],dfn[v]); } if(low[x]==dfn[x]) { ans++; int v; do { v=q.top(); q.pop(); instack[v]=0; } while(v!=x); } } int main() { int x,y; while(scanf("%d%d",&n,&m)&&(m+n)) { for(int i=1; i<=n; i++) { ve[i].clear(); instack[i]=vis[i]=0; } while(!q.empty()) q.pop(); for(int i=0; i<m; i++) { scanf("%d%d",&x,&y); ve[x].push_back(y); } nncount=ans=0; for(int i=1; i<=n; i++) if(!vis[i]) tarjin(i); if(ans==1) puts("Yes"); else puts("No"); } return 0; }
其实这道题还可以用并查集来做;
维护两个数组,一个找儿子,一个找爸爸就行;
我也是参考别人的代码写的;
不过挺不错的,好好学习了下!
1 #include<cstdio> 2 using namespace std; 3 int f[10005],d[10005],n,m; 4 int find1(int x) 5 { 6 if(x!=1&&f[x]!=x) 7 f[x]=find1(f[x]); 8 return f[x]; 9 } 10 11 int find2(int x) 12 { 13 if(x!=1&&d[x]!=x) 14 d[x]=find2(d[x]); 15 return d[x]; 16 } 17 18 void uni(int x,int y) 19 { 20 if(x>1) f[x]=find1(y); 21 if(y>1) d[y]=find2(x); 22 } 23 24 bool judge() 25 { 26 for(int i=2; i<=n; i++) 27 if(find1(i)!=1||find2(i)!=1) 28 return 1; 29 return 0; 30 } 31 32 int main() 33 { 34 int x,y; 35 while(scanf("%d%d",&n,&m)&&(n+m)) 36 { 37 for(int i=1; i<=n; i++) 38 f[i]=i,d[i]=i; 39 for(int i=0; i<m; i++) 40 { 41 scanf("%d%d",&x,&y); 42 uni(x,y); 43 } 44 if(judge()) puts("No"); 45 else puts("Yes"); 46 } 47 return 0; 48 }