poj 2762 Going from u to v or from v to u?(强连通、缩点、拓扑)
2013-10-05 13:11
423 查看
题意:(理解错了)在一个洞穴中有多个room,要求任意选两个room:u、v,都能保证u、v之间有通路,注意洞穴中的路是有向边。、
分析:强连通子图中的点必然两两之间可以互通,两个强连通子图之间有通路,必须在树上构成父子关系(不一定相邻),又两两之间有通路,即任意两个点u、v都存在父子关系——所有强连通子图构成一条链。
错误:tarjin初始化忘记更新scc_cnt=dfs_clock=0;
View Code
分析:强连通子图中的点必然两两之间可以互通,两个强连通子图之间有通路,必须在树上构成父子关系(不一定相邻),又两两之间有通路,即任意两个点u、v都存在父子关系——所有强连通子图构成一条链。
错误:tarjin初始化忘记更新scc_cnt=dfs_clock=0;
#include<cstdio> #include<cstring> #include<queue> #include<stack> #include<vector> #include<algorithm> using namespace std; const int MAXN=1111; struct Edge{ int v,next; Edge(){} Edge(int _v,int _next):v(_v),next(_next){} }edge[MAXN*10]; struct Tp{ int u,c; Tp(){} Tp(int _u,int _c):u(_u),c(_c){} }; int pre[MAXN],low[MAXN],sccno[MAXN],scc_cnt,dfs_clock; int head[MAXN],tol; stack<int>stk; //int mp[MAXN][MAXN];//去重边反而跑的时间更长 vector<int>G[MAXN]; int in[MAXN],color[MAXN]; queue<Tp>q; void init() { tol=0; memset(head,-1,sizeof(head)); } void add(int u,int v) { edge[tol]=Edge(v,head[u]); head[u]=tol++; } void dfs(int u) { int v; pre[u]=low[u]=++dfs_clock; stk.push(u); for(int i=head[u];i!=-1;i=edge[i].next) { v=edge[i].v; if(!pre[v]){ dfs(v); low[u]=min(low[u],low[v]); }else if(!sccno[v]) low[u]=min(low[u],pre[v]); } if(pre[u]==low[u]){ scc_cnt++; do{ v=stk.top(); stk.pop(); sccno[v]=scc_cnt; }while(u!=v); } } void find_scc(int n) { dfs_clock=scc_cnt=0; memset(pre,0,sizeof(pre)); memset(low,0,sizeof(low)); memset(sccno,0,sizeof(sccno)); for(int i=1;i<=n;i++) if(!pre[i]) dfs(i); } int main() { int T; int n,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); init(); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); } find_scc(n); memset(in,0,sizeof(in)); for(int i=1;i<=scc_cnt;i++) G[i].clear(); //memset(mp,0,sizeof(mp)); for(int i=1;i<=n;i++) for(int j=head[i];j!=-1;j=edge[j].next) if(sccno[i]!=sccno[edge[j].v]){ //if(mp[sccno[i]][sccno[edge[j].v]]==0){ G[sccno[i]].push_back(sccno[edge[j].v]); //mp[sccno[i]][sccno[edge[j].v]]=1; in[sccno[edge[j].v]]++; //} } for(int i=1;i<=scc_cnt;i++) if(!in[i]) q.push(Tp(i,1)); memset(color,0,sizeof(color)); Tp e; while(!q.empty()) { e=q.front();q.pop(); color[e.c]++; int sz=G[e.u].size(); for(int i=0;i<sz;i++) { in[G[e.u][i]]--; if(in[G[e.u][i]]==0){ q.push(Tp(G[e.u][i],e.c+1)); } } } int flog=1; for(int i=1;i<=e.c;i++) if(color[i]>1){ flog=0; break; } if(!flog) printf("No\n"); else printf("Yes\n"); } return 0; }
View Code
相关文章推荐
- 用django搭建一个简易blog系统(翻译)(二)
- UVa 686 Goldbach's Conjecture (II) (哥德巴赫猜想)
- UVa 543 Goldbach's Conjecture (素数&哥德巴赫猜想)
- The Go Programming Language Specification
- 2013 MPD SZ会议小结及书评 - How Google Test Software
- Map-Reduce Algorithm Design
- 算法学习 - Dijkstra's Algorithm
- [POJ][1003]Hangover
- Manacher's ALGORITHM
- 匈牙利算法Hungarian algorithm
- single number
- hdu 2401 Baskets of Gold Coins
- 解决google服务框架、google play、google地图、google搜索等基本的应用无使用最简单的方法
- 安装google+时提醒手机中没有该应用所需的共享库的解决方法
- The rsync algorithm
- Google发布Chrome 30:支持图片搜索及安卓端的一些新手势
- LOGO中的隐含信息
- Google发布Chrome 30:支持图片搜索及安卓端的一些新手势
- Single Number II
- spoj AMR11 Robbing Gringotts 双边暴力+hash+费用流