【缩点+拓扑判链】POJ2762 Going from u to v or from v to u?

Description

In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn‘t know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

Solution

缩点,满足题意的充要条件是存在一条完整的链,这个可以用“是否存在唯一拓扑序”解决。

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=1e5+5;
 6
 7 int pre[maxn],low[maxn],clock;
 8 int scc[maxn],s[maxn],c,cnt;
 9 int head[maxn],e[maxn],nxt[maxn],k;
10 void adde(int u,int v){
11     e[++k]=v;nxt[k]=head[u];head[u]=k;
12 }
13 int _head[maxn],_e[maxn],_nxt[maxn],_k;
14 void _adde(int u,int v){
15     _e[++_k]=v;_nxt[_k]=_head[u];_head[u]=_k;
16 }
17 int n,m;
18
19 int r[maxn],vis[maxn];
20 int topo(){
21     for(int i=1;i<=cnt;i++){
22         int tot=0,u;
23         for(int i=1;i<=cnt;i++)//偷懒
24             if(!r[i]&&!vis[i]) tot++,u=i;
25         if(tot>1) return 0;
26         vis[u]=1;
27         for(int i=_head[u];i;i=_nxt[i])
28             r[_e[i]]--;
29     }
30     return 1;
31 }
32
33 void dfs(int u){
34     pre[u]=low[u]=++clock;
35     s[++c]=u;
36     for(int i=head[u];i;i=nxt[i]){
37         int v=e[i];
38         if(!pre[v]){
39             dfs(v);
40             low[u]=min(low[u],low[v]);
41         }
42         else if(!scc[v]){
43             low[u]=min(low[u],pre[v]);
44         }
45     }
46     if(low[u]==pre[u]){
47         cnt++;
48         while(c){
49             scc[s[c]]=cnt;
50             if(s[c--]==u) break;
51         }
52     }
53 }
54
55 void clear(){
56     memset(head,0,sizeof(head));
57     memset(_head,0,sizeof(_head));
58     memset(pre,0,sizeof(pre));
59     memset(low,0,sizeof(low));
60     memset(vis,0,sizeof(vis));
61     memset(r,0,sizeof(r));
62     c=cnt=k=_k=0;
63 }
64
65 int main(){
66     int T;
67     scanf("%d",&T);
68     while(T--){
69         clear();
70         scanf("%d%d",&n,&m);
71         for(int i=1;i<=m;i++){
72             int u,v;
73             scanf("%d%d",&u,&v);
74             adde(u,v);
75         }
76         for(int i=1;i<=n;i++)
77             if(!pre[i]) dfs(i);
78
79         for(int i=1;i<=n;i++)
80             for(int j=head[i];j;j=nxt[j]){
81                 int u=scc[i],v=scc[e[j]];
82                 if(u==v) continue;
83                 else _adde(u,v),r[v]++;
84             }
85
86         if(topo()) printf("Yes\n");
87         else printf("No\n");
88     }
89     return 0;
90 }
时间: 2024-12-16 14:11:47

【缩点+拓扑判链】POJ2762 Going from u to v or from v to u?的相关文章

ZOJ 3795 Grouping 强联通缩点+拓扑序+偏序集的最大链的大小

题意:有n个人,m个关系,关系是这两个人前一个人可以跟后一个比较. 那么问你我最少分多少组可以使这个组里的人都不可以比较. 只会强联通缩点,真特么不知道怎么做,想了一个小时,网上一看,还要会偏序集的东西,有一个叫Dilworth定理的东西. 定理1 令(X,≤)是一个有限偏序集,并令r是其最大链的大小.则X可以被划分成r个但不能再少的反链. 其对偶定理称为Dilworth定理: 定理2 令(X,≤)是一个有限偏序集,并令m是反链的最大的大小.则X可以被划分成m个但不能再少的链. 然后我们用到的是

poj2762 Going from u to v or from v to u? --- 缩点+拓扑

给一个有向图,问是否该图上任意两点间可达. 首先容易想到缩点成有向无环图,其次就是如何处理任意两点间可达. 我在纸上画了一些情况: 4 3 1 2 2 3 2 4 4 4 1 2 1 3 2 4 3 4 3 3 1 2 2 3 1 3 7 8 1 2 1 3 3 4 2 4 4 5 4 6 5 7 6 7 5 6 1 2 1 3 2 3 3 4 3 5 4 5 NNYNY 根据这里一直在纠结如何通过入度出度直接判断.但是一直觉得不严谨.. 然后发现只要拓扑序列唯一即可.这样图中就没有 没有关系的

POJ2762 Going from u to v or from v to u?(强连通缩点+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15196   Accepted: 4013 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

[poj2762] Going from u to v or from v to u?(Kosaraju缩点+拓排)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14778   Accepted: 3911 Description In order to make their sons brave, Jiajia and Wind take them

bzoj2208: [Jsoi2010]连通数 缩点+拓扑+状压

tarjan缩点后拓扑排序,每一个点用一个bitset记录哪些点能到达它. PS:数据太水,暴力能过. #include<bits/stdc++.h> using namespace std; #define N 2010 struct edge{ edge* s; int v; }e[N*N*2],*back=e,*h[N]; int low[N],num[N],scc[N],size[N]; int now; void tarjan(int u){ static int cnt; stat

UVA 11324.The Largest Clique tarjan缩点+拓扑dp

题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以). 思路:同一个强联通分量中满足结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以).把强联通分量收缩点后得到scc图,让每个scc结点的权值等于他的结点数,则求scc图上权最大的路径.拓扑dp,也可以直接bfs,但是要建立一个新的起点,连接所有入度为0

POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)

Countries in War Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Appoint description: Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The impor

POJ 2762判断单联通(强连通缩点+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14789   Accepted: 3915 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

UVALive 6195 The Dueling Philosophers Problem 强连通缩点+拓扑序

题目链接:点击打开链接 给定n个点m条限制 下面限制 u->v 表示u必须排在v前面,问把n个数排成一排有多少种方法. 若有0种输出0 1种输出1 多种输出2 **边的数量题目里少了个0== 思路: 0种就是有环,缩点一下判断强连通分量是不是n个. 1种就是拓扑序时队列里任何时刻都只有一个点 否则就是2种 #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include