hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
2017-08-23 17:51
274 查看
题目思路倒是不难,我做的时候画了画样例,就感觉只要这个有向图能被一条单向路径串起来成一个链,也就是根单向的直线,那情侣就赢了。否则,就完了。因为成了一个单向的链后,任意两点,都可以从某一点到达另一点。不过,我不会写代码怎么验证有向图是个单向的链,然后就处于懵逼中。这刚学了tarjan缩点,才来做。
#include <bits/stdc++.h> using namespace std; const int MAXN = 1010; const int MAXM = 6010; struct Edge { int to,next; } edge[MAXM]; int head[MAXN],tot; //Belong[i]表示点i属于第Belong[i]个强连通分量 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN]; int Index,top; int scc; bool Instack[MAXN]; void init() { tot = 0; memset(head,-1,sizeof(head)); } void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void Tarjan(int u) { int v; Low[u] = DFN[u] = ++Index; Stack[top++] = u; Instack[u] = true; for(int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(!DFN[v]) { Tarjan(v); if(Low[u] > Low[v]) Low[u] = Low[v]; } else if(Instack[v] && Low[u] > DFN[v]) Low[u] = DFN[v]; } if(Low[u] == DFN[u]) { scc++; do { v = Stack[--top]; Instack[v] = false; Belong[v] = scc; } while(v != u); } } void solve(int N) { memset(DFN,0,sizeof(DFN)); memset(Instack,false,sizeof(Instack)); Index = scc = top = 0; for(int i = 1; i <= N; ++i) if(!DFN[i]) Tarjan(i); } int degree[MAXN]; vector<int> G[MAXN]; void work(int n, int m) { memset(degree,0,sizeof(degree)); for(int i = 1; i <= n; ++i) G[i].clear(); int u,v; for(int i = 1; i <= n; ++i) { for(int j = head[i]; j != -1; j = edge[j].next) { u = Belong[i]; v = Belong[edge[j].to]; if(u != v) { G[u].push_back(v); degree[v]++; } } } int cnt = 0; int p; for(int i = 1; i <= scc; ++i) { if(degree[i] == 0) ++cnt,p=i; if(cnt > 1) break; } if(cnt > 1) { printf("Light my fire!\n"); return; } cnt = 0; queue<int> que; que.push(p); bool flag = false; while(!que.empty()) { int q = que.front(); que.pop(); cnt = 0; for(int i = 0; i < G[q].size(); ++i) { degree[G[q][i]]--; if(degree[G[q][i]] == 0) { ++cnt; que.push(G[q][i]); } } if(cnt > 1) { flag = true; break; } } if(flag) printf("Light my fire!\n"); else printf("I love you my love and our love save us!\n"); } int main() { int T; scanf("%d",&T); while(T--) { init(); int n,m,a,b; scanf("%d %d",&n,&m); for(int i = 0; i < m; ++i) { scanf("%d %d",&a,&b); addedge(a,b); } solve(n); work(n,m); } return 0; }
相关文章推荐
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine(强连通分量缩点+拓扑排序)
- hdu 6165 FFF at Valentine
- HDU-6165 FFF at Valentine - 2017 Multi-University Training Contest - Team 9(强连通分量缩点+拓扑)
- 【多校训练】hdu 6165 FFF at Valentine
- HDU 6165 FFF at Valentine
- HDU --- 6165 FFF at Valentine 多校第九场 【强联通缩点 + 维护拓扑序】