[HDOJ6165] FFF at Valentine(强联通分量,缩点,拓扑排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6165

题意:问一个有向图中是否有任意两点可以到达。

读错题就彻底输了,读成判断是否有任意条路,使得经过所有点并且每条边最多走一次。

强联通缩点,然后维护拓扑序,假如拓扑序中有两个以上点入度为0,那么这几个点之间就不能互相到达了。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 namespace fastIO {
  5     #define BUF_SIZE 20
  6     bool IOerror = 0;
  7     inline char nc() {
  8         static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
  9         if (p1 == pend) {
 10             p1 = buf;
 11             pend = buf + fread(buf, 1, BUF_SIZE, stdin);
 12             if (pend == p1) {
 13                 IOerror = 1;
 14                 return -1;
 15             }
 16         }
 17         return *p1++;
 18     }
 19     inline bool blank(char ch) {
 20         return ch == ‘ ‘ || ch == ‘\n‘ || ch == ‘\r‘ || ch == ‘\t‘;
 21     }
 22     inline void read(int &x) {
 23         char ch;
 24         while (blank(ch = nc()));
 25         if (IOerror)
 26             return;
 27         for (x = ch - ‘0‘; (ch = nc()) >= ‘0‘ && ch <= ‘9‘; x = x * 10 + ch - ‘0‘);
 28     }
 29     #undef BUF_SIZE
 30 };
 31
 32 const int maxn = 1010;
 33 const int maxm = 6060;
 34 typedef struct Edge {
 35     int u, v, next;
 36     Edge() { next = -1; }
 37 }Edge;
 38 int n, m, cnt;
 39 int head[maxn], ecnt;
 40 Edge edge[maxm];
 41 int bcnt, dindex;
 42 int dfn[maxn], low[maxn];
 43 int stk[maxn], top;
 44 int belong[maxn];
 45 int in[maxn];
 46 bool instk[maxn];
 47 bool vis[maxn];
 48 int f[maxn][maxn];
 49
 50 void init() {
 51     memset(edge, 0, sizeof(edge));
 52     memset(head, -1, sizeof(head));
 53     memset(instk, 0, sizeof(instk));
 54     memset(dfn, 0, sizeof(dfn));
 55     memset(low, 0, sizeof(low));
 56     memset(belong, 0, sizeof(belong));
 57     memset(in, 0, sizeof(in));
 58     ecnt = top = bcnt = dindex = 0;
 59 }
 60
 61 void adde(int uu, int vv) {
 62     edge[ecnt].u = uu;
 63     edge[ecnt].v = vv;
 64     edge[ecnt].next = head[uu];
 65     head[uu] = ecnt++;
 66 }
 67
 68 void tarjan(int u) {
 69     int v = u;
 70     dfn[u] = low[u] = ++dindex;
 71     stk[++top] = u;
 72     instk[u] = 1;
 73     for(int i = head[u]; ~i; i=edge[i].next) {
 74         v = edge[i].v;
 75         if(!dfn[v]) {
 76             tarjan(v);
 77             low[u] = min(low[u], low[v]);
 78         }
 79         else if(instk[v]) low[u] = min(low[u], dfn[v]);
 80     }
 81     if(dfn[u] == low[u]) {
 82         bcnt++;
 83         do {
 84             v = stk[top--];
 85             instk[v] = 0;
 86             belong[v] = bcnt;
 87         } while(v != u);
 88     }
 89 }
 90
 91 queue<int> q;
 92
 93 int check() {
 94     while(!q.empty()) {
 95         int u = q.front(); q.pop();
 96         int tot = 0;
 97         for(int v = 1; v <= bcnt; v++) {
 98             if(!f[u][v]) continue;
 99             in[v]--;
100             if(!in[v]) {
101                 tot++;
102                 q.push(v);
103             }
104         }
105         if(tot >= 2) return puts("Light my fire!");
106     }
107     return puts("I love you my love and our love save us!");
108 }
109
110 signed main() {
111     // freopen("in", "r", stdin);
112     using namespace fastIO;
113     int T, u, v;
114     read(T);
115     while(T--) {
116         read(n); read(m);
117         init();
118         memset(f, 0, sizeof(f));
119         for(int i = 0; i < m; i++) {
120             read(u); read(v);
121             adde(u, v);
122         }
123         for(int i = 1; i <= n; i++) {
124             if(!dfn[i]) tarjan(i);
125         }
126         for(int i = 0; i < ecnt; i++) {
127             u = belong[edge[i].u], v = belong[edge[i].v];
128             if(u == v) continue;
129             if(f[u][v]) continue;
130             f[u][v] = 1; in[v]++;
131         }
132         while(!q.empty()) q.pop();
133         int cnt = 0;
134         for(int i = 1; i <= bcnt; i++) {
135             if(in[i] == 0) {
136                 q.push(i);
137                 cnt++;
138             }
139         }
140         (cnt == 1) ? check() : puts("Light my fire!");
141     }
142     return 0;
143 }
时间: 2024-10-10 13:30:16

[HDOJ6165] FFF at Valentine(强联通分量,缩点,拓扑排序)的相关文章

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

【POJ1236】Network of Schools 强联通分量缩点(本文kosaraju)

/*不要说这题多水之类的--我只是想记一下kosaraju这种屌炸天的dfs序延伸算法(说不定能加到我的ygylca里面)*/ 题意神马的都不说了,好吧,就是给你个图,n个点,然后n行每行都描述该点的出边,图建完了,然后缩点,然后问多少个点没有入度,再问需要加几条边可以让图变强联通图. 强联通图:图中任意两点之间都能互相到达(前提得是有向图你懂的,无向图就有点乱了,根本不要算法了,暴搜就好了) 强联通分量:同强联通图,不过是图中一部分. 缩点,把一个分量视为一个点,缩起来(一般不缩,都是记录每个

hihoCoder#1185 : 连通性&#183;三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值

题目链接: http://hihocoder.com/problemset/problem/1185# 题意: n个点,每个点有一个权值,m条有向边,从1出发,每走到一个点, 就吃掉这个点的草,当没有可以到达的草场或是能够到达的草场都已经被吃光了之后就要返回到1了.求最多可以吃掉多少草. 思路: 提示里面讲的挺好的 如果草场是一个强连通图,那么我们只要走到任意一点,就可以把其他所有的草场都走一遍,并且可以选择任意一个点作为终点.所以把强联通块缩成一个点 因为一个强连通块会被缩成一个点,那么我们可

ZOJ 3795 Grouping(强联通分量 + 缩点 + Dp)

Problem Description: Suppose there are N people in ZJU, whose ages are unknown. We have some messages about them. The i-th message shows that the age of person si is not smaller than the age of person ti. Now we need to divide all these N people into

【强联通分量缩点】【最长路】【spfa】CH Round #59 - OrzCC杯NOIP模拟赛day1 队爷的讲学计划

10分算法:对于城市网络为一条单向链的数据, 20分算法:对于n<=20的数据,暴力搜出所有的可能路径. 结合以上可以得到30分. 60分算法:分析题意可得使者会带着去的城市也就是这个城市所在强联通分量的其他城市,这个过程的代价也就是这个强联通分量的城市数-1,且他可以选择任何一个其中的城市离开这个强联通分量.于是我们求出所有强联通分量,记录下每一个包含的城市数,然后缩点.接下来再用dfs,由于数据是构造的,只能得到60分. 100分算法:在缩点之后,这个图变成了一个有向无环图,我们将一条边连向

【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割

结论: 满足条件一:当一条边的起点和终点不在 残量网络的 一个强联通分量中.且满流. 满足条件二:当一条边的起点和终点分别在 S 和 T 的强联通分量中.且满流.. 网上题解很多的. 1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define IN

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

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

题目链接:https://vjudge.net/contest/295959#problem/I 或者 http://poj.org/problem?id=2762 题意:输入多组样例,输入n个点和m条有向边,问该图中任意两点x, y之间是否满足x可以到y或者y可以到x. 一开始WA的原因是因为没注意到是或者, 如果是并且的话,就是一道简单的强连通分量的题,直接判断整个图是否为一个强连通分量 对于该题, 先用强连通分量进行缩点,简化图.图就变成了DAG,用拓扑排序判断图中点的入度, 图中入度为0

poj 2762 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: 15812   Accepted: 4194 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

【强联通分量缩点】【搜索】bzoj2208 [Jsoi2010]连通数

两次dfs缩点,然后n次dfs暴搜. 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 #define N 2001 6 vector<int>G[N],rG[N],vs,G2[N]; 7 typedef vector<int>::iterator ITER; 8 char s[N+1][N+1]; 9 int cmp[N],sum