您的位置:首页 > 编程语言 > Go语言

[POJ2762]Going from u to v or from v to u?

2017-08-25 19:18 260 查看

题目大意:
判断一个有向图是否弱连通。

思路:
Tarjan缩点。然后判断原图是否是一条链。
考虑链的特性:有且仅有一点入度为0,有且仅有一点出度为0。
因此缩点后直接判断入度为0和出度为0的点的个数是否均为1即可。

 

#include<stack>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
inline int getint() {
char ch;
while(!isdigit(ch=getchar()));
int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int V=1001;
std::vector<int> e[V];
inline void add_edge(const int u,const int v) {
e[u].push_back(v);
}
int dfn[V],low[V],scc[V],in[V],out[V],cnt,id;
bool ins[V];
std::stack<int> s;
inline void init() {
for(int i=0;i<V;i++) e[i].clear();
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(scc,0,sizeof scc);
memset(ins,0,sizeof ins);
memset(in,0,sizeof in);
memset(out,0,sizeof out);
cnt=id=0;
}
void Tarjan(const int x) {
dfn[x]=low[x]=++cnt;
s.push(x);
ins[x]=true;
for(unsigned i=0;i<e[x].size();i++) {
int &y=e[x][i];
if(!dfn[y]) {
Tarjan(y);
low[x]=std::min(low[x],low[y]);
}
else if(ins[y]) {
low[x]=std::min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x]) {
int y;
++id;
do {
y=s.top();
s.pop();
ins[y]=false;
scc[y]=id;
} while(y!=x);
}
}
int main() {
for(int T=getint();T;T--) {
int n=getint();
init();
for(int m=getint();m;m--) {
int u=getint(),v=getint();
add_edge(u,v);
}
for(int i=1;i<=n;i++) {
if(!dfn[i]) Tarjan(i);
}
for(int x=1;x<=n;x++) {
for(unsigned i=0;i<e[x].size();i++) {
int &y=e[x][i];
if(scc[x]!=scc[y]) out[scc[x]]++,in[scc[y]]++;
}
}
int cin=0,cout=0;
for(int i=1;i<=id;i++) {
if(!in[i]) cin++;
if(!out[i]) cout++;
}
puts(cin==1&&cout==1?"Yes":"No");
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: