题目大意:给定n条单向边,求图中任意两点的连通路径的数目。其中点是从0-输入中出现的最大的点。
可以用floyd-warshall算法或者dfs.
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j++)
dp[i][j] += dp[i][k] * dp[k][j];
这里这样写是不会重复的,原因在于k循环时,可能产生重复情况的 点对应的d[k][j]或d[i][k]为0,因此一条分支路径上最终只会算一遍,不同的分叉加起来就是总数目。
在判断环存在时,若dp[k][k]不为0,说明k点在环上,所有路径经过k的dp[i][j]都应该变成-1,也就是对应无数条这样的i->j的通路。
1 #include <cstdio>
2 #include <cstring>
3 #include <cstdlib>
4 #include <algorithm>
5 #define N 30
6 using namespace std;
7 int n, m, dp[N][N];
8
9 void floyd(void)
10 {
11 for(int k = 0; k < n; k++)
12 for(int i = 0; i < n; i++)
13 for(int j = 0; j < n; j++)
14 dp[i][j] += dp[i][k] * dp[k][j];
15 for(int k = 0; k < n; k++)
16 if(dp[k][k])
17 for(int i = 0; i < n; i++)
18 for(int j = 0; j < n; j++)
19 if(dp[i][k] && dp[k][j])
20 dp[i][j] = -1;
21
22 }
23
24 void out(void)
25 {
26 for(int i = 0; i < n; i++)
27 {
28 for(int j = 0; j < n; j++)
29 printf("%d%c",dp[i][j], (j == n-1)? '\n':' ');
30
31 }
32 }
33 int main(void)
34 {
35 int t = 0;
36 while(~scanf("%d", &m))
37 {
38 n = 0;
39 memset(dp, 0, sizeof(dp));
40 printf("matrix for city %d\n", t++);
41 while(m--)
42 {
43 int a, b;
44 scanf("%d%d",&a, &b);
45 dp[a][b] = 1;
46 n = max(n, max(a, b));
47 }
48 n++;
49 floyd();
50 out();
51 }
52 return 0;
53 }
或者采用dfs的方法,代码参考于这位大神:
http://www.cnblogs.com/devymex/archive/2010/08/17/1801126.html
其实我自己又照着写了一遍,稍微改动了。
我来再叙述一遍加深自己的理解:
通过vector<int>Path保存经过的点,并在dfs搜索下一个点之后再已经走过的Path里面查找看是否存在相应点,如果存在说明该重复结点到Path的最后一个点形成环,应该把数目设成-1,然后跳过改重复点,dfs下一个结点,注意每次dfs完之后都要将相应结点从Path里面移出来,
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #include <vector>
5 using namespace std;
6 #define N 30
7 #define Rep(i,c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
8 vector<int> g[N];
9 int res[N][N];
10
11 void dfs(vector<int> &Path)
12 {
13 vector<int> &temp = g[Path.back()];
14 Rep(i,temp)
15 {
16 vector<int> ::iterator j = Path.begin();
17 for(; j != Path.end(); j++)
18 if(*j == *i)
19 break;
20 if(j != Path.end())
21 {
22 for(; j != Path.end(); j++)
23 res[*j][*j] = -1;
24 continue;
25 }
26 res[Path.front()][*i] ++;
27 Path.push_back(*i);
28 dfs(Path);
29 Path.pop_back();
30 }
31 }
32
33 int main(void)
34 {
35 int t = 0;
36 int m, n;
37 while(~scanf("%d", &m))
38 {
39 memset(res, 0,sizeof(res));
40 n = 0;
41 printf("matrix for city %d\n", t++);
42 for(int i = 0; i < N; i++)
43 g[i].clear();
44 while(m--)
45 {
46 int a, b;
47 scanf("%d%d",&a, &b);
48 g[a].push_back(b);
49 n = max(n, max(a, b));
50 }
51 n++;
52 for(int i = 0; i < n; i++)
53 {
54 vector<int> Path(1,i);
55 dfs(Path);
56 }
57 for(int k = 0; k < n; k++)
58 if(res[k][k] == -1)
59 for(int i = 0; i < n; i++)
60 for(int j = 0; j < n; j++)
61 if(res[i][k] && res[k][j])
62 res[i][j] = -1;
63 for(int i = 0; i < n; i++)
64 for(int j = 0; j < n; j++)
65 printf("%d%c", res[i][j],(j == n-1)?'\n':' ');
66 }
67 return 0;
68 }