poj 2762 强连通缩点+拓扑排序
来源:互联网 发布:php打表格 编辑:程序博客网 时间:2024/05/18 02:06
这题搞了好久,先是拓扑排序这里没想到,一开始自己傻乎乎的跑去找每层出度为1的点,然后才想到能用拓扑排序来弄。
拓扑排序的时候也弄了挺久的,拓扑排序用的也不多。
题意:给一个图求是否从对于任意两个点能从v 到w 或者从w到v连通。
思路:单连通,先强连通缩点,若scnt为1,或者出度为零的点为0,直接输出YES,若出度为零的点大于1,则代表有分支输出NO。若出度为零的点为1,判断组成的树是否为单链,即没有分支,用拓扑排序即可。
代码:
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define MAXN 1100#define MAXM 6600struct Edge{ int to,next;}edge[MAXM];int first[MAXN], stack[MAXN], DFN[MAXN], Low[MAXN], Belong[MAXN];int indegree[MAXN],instack[MAXN];int n,m,tot,scnt,top,cnt;bool new_map[MAXN][MAXN];int vis[MAXN];void Tarjan(int v){ int min,t; DFN[v]=Low[v]=++tot; instack[v]=1; stack[top++]=v; for(int e=first[v];e!=-1;e=edge[e].next) { int j=edge[e].to; if(!DFN[j]) { Tarjan(j); if(Low[v]>Low[j])Low[v]=Low[j]; } else if(instack[j]&&DFN[j]<Low[v]) { Low[v]=DFN[j]; } } if(DFN[v]==Low[v]) { scnt++; do { t=stack[--top]; instack[t]=0; Belong[t]=scnt; }while(t!=v); }}void read_graph(int v,int w){ edge[tot].to=w; edge[tot].next=first[v]; first[v]=tot++;}void solve(){ for(int i=1;i<=n;i++) if(!DFN[i]) Tarjan(i);}void process(int j,int n){ for(int i=1;i!=n+1;i++) { if(new_map[j][i]) indegree[i]--; }}int check(int n){ int count(0); int t(0); for(int i=1;i!=n+1;i++) { if(vis[i]==false&&indegree[i]==0) { t=i; vis[i] = true; count++; } } if(t!=0) process(t,n); return count;}bool topo_sort(int n){ memset(vis,false,sizeof(vis)); for(int i=1;i!=n+1;i++) { if(check(n)>1) return false; } return true;}int main(){ int T; scanf("%d",&T); while(T--) { memset(indegree,0,sizeof(indegree)); memset(DFN,0,sizeof(DFN)); memset(first,-1,sizeof(first)); cnt=scnt=tot=top=0; memset(new_map,false,sizeof(new_map)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int v,w; scanf("%d%d",&v,&w); read_graph(v,w); } solve(); //cout<<scnt<<endl; if(scnt==1) { printf("Yes\n"); continue; } for(int i=1;i<=n;i++) { for(int j=first[i];j!=-1;j=edge[j].next) { int v=edge[j].to; if(Belong[i]!=Belong[v]) { new_map[Belong[i]][Belong[v]] = true; indegree[Belong[v]]++; } } } int count1=0; for(int i=1;i<=scnt;i++) { if(indegree[i]==0) count1++; } if(count1==0) { printf("Yes\n"); continue; } else if(count1>1) { printf("No\n"); continue; } if(topo_sort(scnt)) printf("Yes\n"); else printf("No\n"); } return 0;}
- poj 2762 强连通缩点+拓扑排序
- POJ 2762 证明是否为单向连通图 强连通缩点+类拓扑排序
- POJ 2762判断单联通(强连通缩点+拓扑排序)
- poj 2762 (强连通缩点)
- UVA 11770 Lighting Away 强连通缩点+拓扑排序
- HDU6165(tarjan算法 强连通缩点,拓扑排序)
- poj 3160 (强连通缩点)
- poj 2186 (强连通缩点)
- poj 3114(强连通缩点+SPFA)
- POJ 2186 强连通缩点
- 强连通缩点
- 强连通缩点
- zoj 3795 Grouping 强连通缩点+拓扑排序最长链
- HDU2767 强连通缩点
- poj1236强连通缩点
- Semiconnected--强连通缩点
- 强连通缩点 hdu3072
- POJ2762 Going from u to v or from v to u?(强连通缩点+拓扑排序)
- 09-php接口
- hdu 4308 Saving Princess claire_(bfs)
- 线程的生命周期
- HDU2680 Choose the best route 解题报告--Dijkstra
- java中volatile关键字的含义
- poj 2762 强连通缩点+拓扑排序
- 存储器芯片
- jQuery:jQuery性能优化28条建议
- python手记(24)
- LeetCode-Count and Say
- C语言多线程-读写公共数据缓冲区
- ios 带推送服务的证书的申请与不带此服务的区别
- opencv 图像的边缘
- 用牛顿迭代法求根号2及sqrt(任意数),连续求解,保留小数点后16位