Description



KJZ的师弟师妹们最近在学习离散数学,于是他决定出一道简单的图论知识考考大家! 在这里他向大家介绍了一个叫做传递闭包的概念。 传递闭包就是,在集合X上的二元关系R的传递闭包是包含R的X上的最小的传递关系。 那么什么事有向图的传递闭包呢? 对于有向图G(V,E)的传递闭包即是G(V,E),其中E{(i,j):图G中包含一条由i到j的路径}。 读到这里的你,如果是一头雾水的话,证明你集合论学的不是很好,一定要认真听离散数学的课程喔! 但是KJZ是一名尽职的师兄,他在这里通过一道题目,向你通俗易懂的介绍什么是有向图的传递闭包。



Input



每个输入只有一组 每组输入第一行包括一个整数N(1<=N<=300) 接下来N行N列,代表一个矩阵G 如果G[i][j] = 1,代表i有一条边连向j 如果G[i][j] = 0,代表i没有边连向j 且对于1~N,G[i][i]必定等于1 接下来一个数字Q,代表有Q次查询 (1<=Q<=100000) 接下来有Q行,每行两个数字u,v



Output



对于每个查询u,v,输出一行,如果u能走到v,输出1,否则输出0



Sample Input 1



3
1 1 0
0 1 1
0 0 1
5
1 1
1 3
2 3
3 2
3 1



Sample Output 1



1
1
1
0
0



解题思路:这道题的思路非常巧妙,就是利用Floyd的最短路径,假设能找到“最短路径”则证明是连通的,不能则证明不联通;



Floyd算法大概思想:依次扫描每一点(k),并以该点作为中介点,计算出通过k点的其他任意两点(i,j)的最短距离,这就是floyd算法的精髓



也就是说起点i 直接到达终点 j 最短 还是从i 出发 经过中间 若干点 k  到达 j 最短;



实现只需要三个循环:



1 for(int k = 1 ; k  <= N ;k++)      //k表示的是中间经过的点,这个循环一定要放在最外面
2    for(int i  = 1 ; i <= N; i++)
3        for(int j = 1  ; j <= N ;j++)
4           dp[i][j] = min(dp[i][j],d[i][k]+d[k][j]);      //不断取“最小”;



回归这道题,我们也可以以这种思想,从该起点 i 出发,看是否经过中间 k 点 ,能到达 j点;或者从i 直接到达 j 点;

代码如下:



1 #include<iostream>
 2 using namespace std;
 3 
 4 
 5 int N;
 6 int Q;
 7 int x ,y;
 8 int G[305][305];
 9 int map[305][305];
10 int main()
11 {
12     cin>>N;
13     for(int i = 1 ;i <= N;i++)
14     {
15         for(int j = 1 ; j <= N;j++)
16         {
17             cin>>G[i][j];           //输入这个矩阵
18         }
19     }
20       
21     for(int k = 1 ; k <= N ;k++)     //这个中间点的循环一定要放在最外面;
22     {
23         for(int i = 1 ;i <= N; i++)
24         {
25             for(int j = 1 ; j <= N;j++)
26             {
27                 if(G[i][j]==1||G[i][k]==1&&G[k][j]==1) 
28                            //直接连通或者间接经过其他点连通;
29                 {
30                     map[i][j] = 1;  //将这两点连通;
31                  } 
32             }
33         }
34     }
35     cin>>Q;
36     for(int i = 1 ; i <= Q ;i++)
37     {
38         cin>>x>>y;
39         if(map[x][y]==1)    //判断两点是否连通
40         cout<<1<<endl;
41         else cout<<0<<endl;
42     }
43     return 0;
44 }