hdu 6165

题意:n,m,n个点,m条边,问对于任意2个位置,是否可以从一个点到达另一个点

思路:缩点后,预处理出,每一个联通块能到达的联通块。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #pragma comment(linker, "/STACK:102400000,102400000")
  4 const int N=40003;
  5 const int M=40003;
  6
  7 struct node
  8 {
  9     int from,to,next;
 10 } e[M];
 11 int head[N],tot;
 12 int dfn[N],low[N],belong[N];
 13 int instack[N];
 14 int Stack[N],index1,top,bcnt;
 15
 16 void add(int u,int v)
 17 {
 18     e[tot].from=u;
 19     e[tot].to=v;
 20     e[tot].next=head[u];
 21     head[u]=tot++;
 22 }
 23 vector<int > g[N];
 24 int go[2000][2000];
 25 int n,m;
 26 void init()
 27 {
 28     tot=1;
 29     memset(go,0,sizeof(go));
 30     memset(dfn,0,sizeof(dfn));
 31     memset(belong,0,sizeof(belong));
 32     memset(head,-1,sizeof(head));
 33     index1=top=bcnt=0;
 34 }
 35
 36 void tarjan(int u)
 37 {
 38     dfn[u]=low[u]=++index1;
 39     instack[u]=1;
 40     Stack[++top]=u;
 41     for(int i=head[u]; i!=-1; i=e[i].next)
 42     {
 43         int v=e[i].to;
 44         if(!dfn[v])
 45         {
 46             tarjan(v);
 47             low[u]=min(low[u],low[v]);
 48         }
 49         else if(instack[v])
 50         {
 51             low[u]=min(low[u],dfn[v]);
 52         }
 53     }
 54     int v;
 55     if(dfn[u]==low[u])
 56     {
 57         bcnt++;
 58         do
 59         {
 60             v=Stack[top--];
 61             instack[v]=0;
 62             belong[v]=bcnt;
 63         }
 64         while(u!=v);
 65     }
 66 }
 67
 68 void dfs(int u,int zu) {
 69     for(int i=0;i<g[u].size();i++){
 70         int v=g[u][i];
 71         go[zu][v]=1;
 72         //cout<<u<<" "<<v<<endl;
 73         dfs(v,zu);
 74     }
 75 }
 76
 77 int main()
 78 {
 79     int t;
 80     cin>>t;
 81     while(t--)
 82     {
 83         int x,y;
 84         init();
 85         scanf("%d%d",&n,&m);
 86         for(int i=1; i<=m; i++)
 87         {
 88             scanf("%d%d",&x,&y);
 89             add(x,y);
 90         }
 91         for(int i=1; i<=n; i++)
 92             if(!dfn[i]) tarjan(i);
 93         for(int i=1; i<=bcnt; i++) g[i].clear();
 94         for(int i=1; i<=m; i++)
 95         {
 96             if(belong[e[i].from]!=belong[e[i].to])
 97             {
 98                 g[belong[e[i].from]].push_back(belong[e[i].to]);
 99             }
100         }
101         for(int i=1; i<=bcnt; i++)
102         {
103             dfs(i,i);
104         }
105         int tt=0;
106
107         for(int i=1; i<=n; i++)
108         {
109             for(int j=i+1; j<=n; j++)
110             {
111                 //cout<<i<<" "<<j<<endl;
112                 if(belong[i]==belong[j]) continue;
113                 int xx=belong[i],yy=belong[j];
114                 if(!go[xx][yy]&&!go[yy][xx])
115                 {
116
117                     tt=1;
118                     break;
119                 }
120             }
121             if(tt) break;
122         }
123         if(tt) printf("Light my fire!\n");
124         else printf("I love you my love and our love save us!\n");
125     }
126     return 0;
127 }
时间: 2024-10-26 10:30:22

hdu 6165的相关文章

HDU 6165 FFF at Valentine(Tarjan缩点+拓扑排序)

FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 575    Accepted Submission(s): 281 Problem Description At Valentine's eve, Shylock and Lucar were enjoying their time as any oth

2017 Multi-University Training Contest - Team 9 1005&amp;&amp;HDU 6165 FFF at Valentine【强联通缩点+拓扑排序】

FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1060    Accepted Submission(s): 506 Problem Description At Valentine's eve, Shylock and Lucar were enjoying their time as any oth

HDU 6165 FFF at Valentine

题目大意:给出一个有向图,问你这个图中是否对于任意两点\(u,v\),都至少满足\(u\to v\)(\(u\)可到达\(v\),下同)或\(v\to u\)中的一个. 一看就是套路的图论题,我们先把边连起来. 考虑一个很基本的性质:在一个强连通分量的点两两可达 于是肯定先Tarjan缩一波点.然后我们得到了一个DAG 接下来就是考虑是否有两个点(当然是缩点之后的了)互不可达. 这个可以直接跑一边拓扑排序.然后看一下是否在某个时刻有两个点的入度为零即可. CODE #include<cstdio

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是

HDU 5917 Instability ramsey定理

http://acm.hdu.edu.cn/showproblem.php?pid=5917 即世界上任意6个人中,总有3个人相互认识,或互相皆不认识. 所以子集 >= 6的一定是合法的. 然后总的子集数目是2^n,减去不合法的,暴力枚举即可. 选了1个肯定不合法,2个也是,3个的话C(n, 3)枚举判断,C(n, 4), C(n, 5) #include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false) using name